diff --git a/.eslintrc.json b/.eslintrc.json index abeff7ac8..fb260f101 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -38,6 +38,7 @@ "import/prefer-default-export": 0, "no-return-assign": 0, "react/require-default-props": 0, - "react/jsx-closing-tag-location": 0 + "react/jsx-closing-tag-location": 0, + "jsx-a11y/no-noninteractive-element-to-interactive-role": 0 } } diff --git a/.gitignore b/.gitignore index 52f16b2e0..4fc96cbb9 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,4 @@ yarn-error.log package-lock.json .idea/ -/build/daemon.ver \ No newline at end of file +/build/daemon* \ No newline at end of file diff --git a/package.json b/package.json index 3ca23f351..37043ce21 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "LBRY", - "version": "0.23.0", + "version": "0.23.1", "description": "A browser for the LBRY network, a digital marketplace controlled by its users.", "keywords": [ "lbry" diff --git a/src/main/createWindow.js b/src/main/createWindow.js index 976e8352b..5d4beff05 100644 --- a/src/main/createWindow.js +++ b/src/main/createWindow.js @@ -1,4 +1,4 @@ -import { app, BrowserWindow, dialog, screen } from 'electron'; +import { app, BrowserWindow, dialog, shell, screen } from 'electron'; import isDev from 'electron-is-dev'; import windowStateKeeper from 'electron-window-state'; @@ -123,6 +123,11 @@ export default appState => { window.webContents.on('crashed', () => { window = null; }); + + window.webContents.on('new-window', (event, url) => { + event.preventDefault(); + shell.openExternal(url); + }); return window; }; diff --git a/src/renderer/component/common/credit-amount.jsx b/src/renderer/component/common/credit-amount.jsx index 0147c0154..67243394f 100644 --- a/src/renderer/component/common/credit-amount.jsx +++ b/src/renderer/component/common/credit-amount.jsx @@ -11,9 +11,10 @@ type Props = { showPlus: boolean, isEstimate?: boolean, large?: boolean, - plain?: boolean, + showLBC?: boolean, fee?: boolean, - noStyle?: boolean, + inheritStyle?: boolean, + filePage?: boolean, }; class CreditAmount extends React.PureComponent { @@ -22,6 +23,7 @@ class CreditAmount extends React.PureComponent { showFree: false, showFullPrice: false, showPlus: false, + showLBC: true, }; render() { @@ -33,9 +35,10 @@ class CreditAmount extends React.PureComponent { showPlus, large, isEstimate, - plain, - noStyle, fee, + showLBC, + inheritStyle, + filePage, } = this.props; const minimumRenderableAmount = 10 ** (-1 * precision); @@ -62,7 +65,7 @@ class CreditAmount extends React.PureComponent { amountText = `+${amountText}`; } - if (!plain) { + if (showLBC) { amountText = `${amountText} ${__('LBC')}`; } @@ -78,8 +81,8 @@ class CreditAmount extends React.PureComponent { 'credit-amount--free': !large && isFree, 'credit-amount--cost': !large && !isFree, 'credit-amount--large': large, - 'credit-amount--plain': plain, - 'credit-amount--no-style': noStyle, + 'credit-amount--inherit': inheritStyle, + 'credit-amount--file-page': filePage, })} > {amountText} diff --git a/src/renderer/component/common/form-components/form-field.jsx b/src/renderer/component/common/form-components/form-field.jsx index 32fa4d9d2..ab8569b9e 100644 --- a/src/renderer/component/common/form-components/form-field.jsx +++ b/src/renderer/component/common/form-components/form-field.jsx @@ -4,7 +4,7 @@ import ReactDOMServer from 'react-dom/server'; import classnames from 'classnames'; import MarkdownPreview from 'component/common/markdown-preview'; import SimpleMDE from 'react-simplemde-editor'; -import 'simplemde/dist/simplemde.min.css'; +import 'simplemde/dist/simplemde.min.css'; // eslint-disable-line import/no-extraneous-dependencies import Toggle from 'react-toggle'; import { openEditorMenu, stopContextMenu } from 'util/contextMenu'; @@ -24,6 +24,7 @@ type Props = { stretch?: boolean, affixClass?: string, // class applied to prefix/postfix label useToggle?: boolean, + firstInList?: boolean, // at the top of a list, no padding top }; export class FormField extends React.PureComponent { @@ -41,6 +42,7 @@ export class FormField extends React.PureComponent { stretch, affixClass, useToggle, + firstInList, ...inputProps } = this.props; @@ -103,6 +105,7 @@ export class FormField extends React.PureComponent {
{prefix && ( diff --git a/src/renderer/component/common/spinner.jsx b/src/renderer/component/common/spinner.jsx deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/renderer/component/fileCard/view.jsx b/src/renderer/component/fileCard/view.jsx index 7a7e4f7d5..f63e23d13 100644 --- a/src/renderer/component/fileCard/view.jsx +++ b/src/renderer/component/fileCard/view.jsx @@ -92,9 +92,8 @@ class FileCard extends React.PureComponent { onContextMenu={handleContextMenu} > -
{showPrice && }
-
+
{title}
@@ -103,13 +102,12 @@ class FileCard extends React.PureComponent { ) : ( -
- {isRewardContent && } - {fileInfo && } -
+ {isRewardContent && } + {fileInfo && }
)}
+ {showPrice && }
); diff --git a/src/renderer/component/filePrice/view.jsx b/src/renderer/component/filePrice/view.jsx index e40a6c25e..ebb0318f1 100644 --- a/src/renderer/component/filePrice/view.jsx +++ b/src/renderer/component/filePrice/view.jsx @@ -9,6 +9,10 @@ type Props = { uri: string, fetching: boolean, claim: ?{}, + // below props are just passed to + filePage?: boolean, + inheritStyle?: boolean, + showLBC?: boolean, }; class FilePrice extends React.PureComponent { @@ -33,13 +37,16 @@ class FilePrice extends React.PureComponent { }; render() { - const { costInfo, showFullPrice } = this.props; + const { costInfo, showFullPrice, filePage, inheritStyle, showLBC } = this.props; return costInfo ? ( ) : null; diff --git a/src/renderer/component/fileTile/view.jsx b/src/renderer/component/fileTile/view.jsx index f7945ed75..2535eb886 100644 --- a/src/renderer/component/fileTile/view.jsx +++ b/src/renderer/component/fileTile/view.jsx @@ -11,7 +11,6 @@ import classnames from 'classnames'; import FilePrice from 'component/filePrice'; type Props = { - fullWidth: boolean, // removes the max-width css showUri: boolean, showLocal: boolean, obscureNsfw: boolean, @@ -28,13 +27,15 @@ type Props = { updatePublishForm: ({}) => void, hideNoResult: boolean, // don't show the tile if there is no claim at this uri displayHiddenMessage?: boolean, + displayDescription?: boolean, + small?: boolean, }; class FileTile extends React.PureComponent { static defaultProps = { showUri: false, showLocal: false, - fullWidth: false, + displayDescription: true, }; componentDidMount() { @@ -57,13 +58,14 @@ class FileTile extends React.PureComponent { showUri, obscureNsfw, claimIsMine, - fullWidth, showLocal, isDownloaded, clearPublish, updatePublishForm, hideNoResult, displayHiddenMessage, + displayDescription, + small, } = this.props; const shouldHide = !claimIsMine && obscureNsfw && metadata && metadata.nsfw; @@ -96,7 +98,7 @@ class FileTile extends React.PureComponent { return !name && hideNoResult ? null : (
{ {isResolvingUri &&
{__('Loading...')}
} {!isResolvingUri && ( -
- {title || name} +
+ {title || name}
-
+
{showUri ? uri : channel || __('Anonymous')} {isRewardContent && } {showLocal && isDownloaded && }
-
- {description} -
-
- -
+ + {displayDescription && ( +
+ {description} +
+ )} {!name && ( {__('This location is unused.')}{' '} diff --git a/src/renderer/component/page/view.jsx b/src/renderer/component/page/view.jsx index 34998d528..7286c9046 100644 --- a/src/renderer/component/page/view.jsx +++ b/src/renderer/component/page/view.jsx @@ -12,6 +12,7 @@ type Props = { noPadding: ?boolean, extraPadding: ?boolean, notContained: ?boolean, // No max-width, but keep the padding + forContent: ?boolean, loading: ?boolean, }; @@ -71,15 +72,24 @@ class Page extends React.PureComponent { loaderTimeout: ?TimeoutID; render() { - const { pageTitle, children, noPadding, extraPadding, notContained, loading } = this.props; + const { + pageTitle, + children, + noPadding, + extraPadding, + notContained, + loading, + forContent, + } = this.props; const { showLoader } = this.state; return (
{pageTitle && ( diff --git a/src/renderer/component/publishForm/view.jsx b/src/renderer/component/publishForm/view.jsx index c291ccaee..dec69e685 100644 --- a/src/renderer/component/publishForm/view.jsx +++ b/src/renderer/component/publishForm/view.jsx @@ -53,7 +53,7 @@ type Props = { clearPublish: () => void, resolveUri: string => void, scrollToTop: () => void, - prepareEdit: ({}) => void, + prepareEdit: ({ }) => void, resetThumbnailStatus: () => void, }; @@ -345,6 +345,13 @@ class PublishForm extends React.PureComponent {
{__('Content')}
{isStillEditing ? __('Editing a claim') : __('What are you publishing?')} + {' '}{__( + 'Read our' + )}{' '} +
{(filePath || !!editingURI) && (
@@ -402,12 +409,12 @@ class PublishForm extends React.PureComponent { {uploadThumbnailStatus === THUMBNAIL_STATUSES.API_DOWN ? ( __('Enter a URL for your thumbnail.') ) : ( - - {__('Upload your thumbnail (.png/.jpg/.jpeg/.gif) to')}{' '} -
{ !channel || channel === CHANNEL_ANONYMOUS || channel === CHANNEL_NEW ? '' : `${channel}/` - }`} + }`} type="text" name="content_name" placeholder="myname" diff --git a/src/renderer/component/recommendedContent/index.js b/src/renderer/component/recommendedContent/index.js new file mode 100644 index 000000000..2588d29c9 --- /dev/null +++ b/src/renderer/component/recommendedContent/index.js @@ -0,0 +1,22 @@ +import * as settings from 'constants/settings'; +import { connect } from 'react-redux'; +import { doFetchClaimsByChannel } from 'redux/actions/content'; +import { makeSelectClaimsInChannelForCurrentPage } from 'lbry-redux'; +import { doSetClientSetting } from 'redux/actions/settings'; +import { makeSelectClientSetting } from 'redux/selectors/settings'; +import RecommendedVideos from './view'; + +const select = (state, props) => ({ + claimsInChannel: makeSelectClaimsInChannelForCurrentPage(props.channelUri)(state), + autoplay: makeSelectClientSetting(settings.AUTOPLAY)(state), +}); + +const perform = dispatch => ({ + fetchClaims: (uri, page) => dispatch(doFetchClaimsByChannel(uri, page)), + setAutoplay: value => dispatch(doSetClientSetting(settings.AUTOPLAY, value)), +}); + +export default connect( + select, + perform +)(RecommendedVideos); diff --git a/src/renderer/component/recommendedContent/view.jsx b/src/renderer/component/recommendedContent/view.jsx new file mode 100644 index 000000000..df2ac55e6 --- /dev/null +++ b/src/renderer/component/recommendedContent/view.jsx @@ -0,0 +1,76 @@ +// @flow +import React from 'react'; +import FileTile from 'component/fileTile'; +import { FormRow, FormField } from 'component/common/form'; +import ToolTip from 'component/common/tooltip'; +import type { Claim } from 'types/claim'; +import { buildURI, parseURI } from 'lbry-redux'; + +type Props = { + uri: string, + channelUri: ?string, + claimsInChannel: ?Array, + autoplay: boolean, + setAutoplay: boolean => void, + fetchClaims: (string, number) => void, +}; + +export default class RecommendedContent extends React.PureComponent { + componentDidMount() { + const { channelUri, fetchClaims, claimsInChannel } = this.props; + if (channelUri && !claimsInChannel) { + fetchClaims(channelUri, 1); + } + } + + render() { + const { claimsInChannel, autoplay, uri, setAutoplay } = this.props; + + let recommendedContent; + if (claimsInChannel) { + recommendedContent = claimsInChannel.filter(claim => { + const { name, claim_id: claimId, channel_name: channelName, value } = claim; + const { isChannel } = parseURI(uri); + + // The uri may include the channel name + const recommendedUri = + isChannel && value && value.publisherSignature + ? buildURI({ + contentName: name, + claimName: channelName, + claimId: value.publisherSignature.certificateId, + }) + : buildURI({ claimName: name, claimId }); + + return recommendedUri !== uri; + }); + } + + return ( +
+ + + setAutoplay(e.target.checked)} + /> + + + {recommendedContent && + recommendedContent.map(({ permanent_url: permanentUrl }) => ( + + ))} +
+ ); + } +} diff --git a/src/renderer/component/rewardSummary/view.jsx b/src/renderer/component/rewardSummary/view.jsx index 0a74fdfb6..87b20ca6c 100644 --- a/src/renderer/component/rewardSummary/view.jsx +++ b/src/renderer/component/rewardSummary/view.jsx @@ -31,7 +31,7 @@ class RewardSummary extends React.Component { {__('You have')}   - +   {__('in unclaimed rewards')}. diff --git a/src/renderer/component/selectThumbnail/view.jsx b/src/renderer/component/selectThumbnail/view.jsx index 1fcd59cb6..a3dd3b208 100644 --- a/src/renderer/component/selectThumbnail/view.jsx +++ b/src/renderer/component/selectThumbnail/view.jsx @@ -18,6 +18,7 @@ type Props = { type State = { thumbnailError: boolean, + thumbnailErrorImage: string, }; class SelectThumbnail extends React.PureComponent { @@ -26,6 +27,7 @@ class SelectThumbnail extends React.PureComponent { this.state = { thumbnailError: false, + thumbnailErrorImage: 'no-thumbnail.png', }; (this: any).handleThumbnailChange = this.handleThumbnailChange.bind(this); @@ -36,7 +38,7 @@ class SelectThumbnail extends React.PureComponent { const newThumbnail = e.target.value.replace(' ', ''); updatePublishForm({ thumbnail: newThumbnail }); - this.setState({ thumbnailError: false }); + this.setState({ thumbnailError: false, thumbnailErrorImage: 'no-thumbnail.png' }); } render() { @@ -49,9 +51,9 @@ class SelectThumbnail extends React.PureComponent { thumbnailPath, resetThumbnailStatus, } = this.props; - const { thumbnailError } = this.state; + const { thumbnailError, thumbnailErrorImage } = this.state; const thumbnailSrc = - !thumbnail || thumbnailError ? Native.imagePath('no-thumbnail.png') : thumbnail; + !thumbnail || thumbnailError ? Native.imagePath(thumbnailErrorImage) : thumbnail; return (
@@ -62,7 +64,11 @@ class SelectThumbnail extends React.PureComponent { className="column__item thumbnail-preview" alt={__('Thumbnail Preview')} onError={() => { - this.setState({ thumbnailError: true }); + this.setState({ + thumbnailError: true, + thumbnailErrorImage: + thumbnail && thumbnail.length > 0 ? 'broken.png' : 'no-thumbnail.png', + }); }} />
diff --git a/src/renderer/component/transactionList/internal/transaction-list-item.jsx b/src/renderer/component/transactionList/internal/transaction-list-item.jsx index 379758722..f59c920a8 100644 --- a/src/renderer/component/transactionList/internal/transaction-list-item.jsx +++ b/src/renderer/component/transactionList/internal/transaction-list-item.jsx @@ -6,8 +6,8 @@ import DateTime from 'component/dateTime'; import Button from 'component/button'; import { buildURI } from 'lbry-redux'; import * as txnTypes from 'constants/transaction_types'; -import type { Transaction } from '../view'; import * as ICONS from 'constants/icons'; +import type { Transaction } from '../view'; type Props = { transaction: Transaction, @@ -25,12 +25,6 @@ class TransactionListItem extends React.PureComponent { (this: any).abandonClaim = this.abandonClaim.bind(this); } - abandonClaim() { - const { txid, nout } = this.props.transaction; - - this.props.revokeClaim(txid, nout); - } - getLink(type: string) { if (type === txnTypes.TIP) { return
+ ))} -
- - -
+
+
+

{title}

+
+ {isRewardContent && } +
- - - + + {__('Published on')}  + + + {metadata.nsfw &&
NSFW
} +
+ +
+
+
+ {claimIsMine ? ( +
+ +
+ + +
-
- )} +
+ + ); } diff --git a/src/renderer/page/search/view.jsx b/src/renderer/page/search/view.jsx index 9e47ebadd..5db8016ee 100644 --- a/src/renderer/page/search/view.jsx +++ b/src/renderer/page/search/view.jsx @@ -73,7 +73,7 @@ class SearchPage extends React.PureComponent {
- + )} diff --git a/src/renderer/redux/actions/publish.js b/src/renderer/redux/actions/publish.js index 3f2f8c871..72926928b 100644 --- a/src/renderer/redux/actions/publish.js +++ b/src/renderer/redux/actions/publish.js @@ -120,7 +120,7 @@ export const doUploadThumbnail = (filePath: string, nsfw: boolean) => (dispatch: thumbnail: `${json.data.url}${fileExt}`, }, }) - : uploadError('Upload failed') + : uploadError(json.message) ) .catch(err => uploadError(err.message)); }; diff --git a/src/renderer/redux/actions/shape_shift.js b/src/renderer/redux/actions/shape_shift.js index d68b54f9c..c2aecefba 100644 --- a/src/renderer/redux/actions/shape_shift.js +++ b/src/renderer/redux/actions/shape_shift.js @@ -74,7 +74,7 @@ export const shapeShiftInit = () => (dispatch: Dispatch): ThunkAction => { let supportedCoins = []; Object.keys(coinData).forEach(symbol => { - if (coinData[symbol].status === SHAPESHIFT_STATUSES.UNAVAILABLE) { + if (coinData[symbol].status === SHAPESHIFT_STATUSES.AVAILABLE) { supportedCoins.push(coinData[symbol]); } }); diff --git a/src/renderer/scss/_gui.scss b/src/renderer/scss/_gui.scss index 9e39927b1..cae904513 100644 --- a/src/renderer/scss/_gui.scss +++ b/src/renderer/scss/_gui.scss @@ -204,6 +204,12 @@ p { padding-right: 100px; } +.main--for-content { + padding: $spacing-width * 2/3; + display: flex; + justify-content: center; +} + .page__header { padding: $spacing-vertical * 2/3; padding-bottom: 0; @@ -251,11 +257,10 @@ p { } .credit-amount { - border-radius: 5px; font-family: 'metropolis-bold'; font-size: 10px; - padding: 5px; white-space: nowrap; + padding: $spacing-vertical * 1/6 0; } .credit-amount--large { @@ -263,30 +268,36 @@ p { font-size: 36px; } +.credit-amount--file-page { + border-radius: 5px; + padding: 5px; +} + .credit-amount--free { - color: var(--color-dark-blue); - background-color: var(--color-secondary); + color: var(--color-secondary); + + &.credit-amount--file-page { + color: var(--color-dark-blue); + background-color: var(--color-secondary); + } } .credit-amount--cost { - color: var(--color-black); - background-color: var(--color-yellow); + color: var(--color-yellow); + + &.credit-amount--file-page { + color: var(--color-black); + background-color: var(--color-yellow); + } } -.credit-amount--plain { +.credit-amount--inherit { background-color: inherit; color: inherit; font-weight: inherit; font-size: inherit; -} - -.credit-amount.credit-amount--no-style { - padding: 0; - font-size: inherit; - font-weight: inherit; - color: inherit; - background-color: transparent; font-family: 'metropolis-medium'; + padding: 0; } .divider__horizontal { diff --git a/src/renderer/scss/_vars.scss b/src/renderer/scss/_vars.scss index 1655a1575..ac80156c0 100644 --- a/src/renderer/scss/_vars.scss +++ b/src/renderer/scss/_vars.scss @@ -9,7 +9,7 @@ $large-breakpoint: 1921px; :root { /* Widths & spacings */ - --side-nav-width: 220px; + --side-nav-width: 190px; --side-nav-width-m: 240px; --side-nav-width-l: 320px; --font-size-subtext-multiple: 0.92; @@ -155,9 +155,14 @@ $large-breakpoint: 1921px; --success-msg-border: var(--color-green-blue); --success-msg-bg: var(--color-green-light); - /* File Tile Card */ - --file-tile--media-height: 125px; - --file-tile--media-width: calc(125px * (16 / 9)); + /* File */ + --file-tile-media-height: 125px; + --file-tile-media-width: calc(125px * (16 / 9)); + --file-tile-media-height-small: 60px; + --file-tile-media-width-small: calc(60px * (16 / 9)); + --file-page-min-width: 400px; + --recommended-content-width: 300px; + --recommended-content-width-medium: 400px; /* Modal */ --modal-width: 440px; diff --git a/src/renderer/scss/component/_card.scss b/src/renderer/scss/component/_card.scss index f44a60d91..40ba15923 100644 --- a/src/renderer/scss/component/_card.scss +++ b/src/renderer/scss/component/_card.scss @@ -38,7 +38,6 @@ @media only screen and (min-width: $medium-breakpoint) { font-size: 14px; - padding-top: 4px; } } } @@ -114,13 +113,17 @@ .card__title--small { font-size: 14px; line-height: 18px; - padding-top: $spacing-vertical / 3; @media only screen and (min-width: $large-breakpoint) { font-size: 16px; } } +.card__title--x-small { + font-size: 12px; + line-height: 12px; +} + .card__title--file { font-family: 'metropolis-bold'; font-size: 28px; @@ -130,25 +133,36 @@ font-size: 18px; } +.card__title--file-card { + padding-top: $spacing-vertical * 1/3; +} + .card__subtitle { margin: 0; font-size: 14px; font-family: 'metropolis-medium'; color: var(--card-text-color); + display: flex; + align-items: center; .icon { - margin-top: $spacing-vertical * 1/6; - - &:not(:first-of-type) { - margin: 0 $spacing-vertical * 1/3; - } + margin: 0 0 0 $spacing-vertical * 1/3; } } +.card__subtitle--x-small { + font-size: 12px; +} + .card__subtitle-price { padding-top: $spacing-vertical * 1/3; } +.card__title--small + .card__subtitle, +.card__title--x-small + .card__subtitle { + padding-top: $spacing-vertical * 1/3; +} + .card__meta { color: var(--color-help); font-size: 14px; @@ -312,7 +326,11 @@ .card-row__scroll-btns { display: flex; - padding-right: $spacing-width; + padding-right: $spacing-width * 1/3; + + @media (min-width: $medium-breakpoint) { + padding-right: $spacing-width; + } } .card-row__scrollhouse { @@ -401,6 +419,15 @@ } } +.card__list--recommended { + flex: 0 0 var(--recommended-content-width); + padding-left: $spacing-width; + + @media (min-width: $medium-breakpoint) { + flex: 0 0 var(--recommended-content-width-medium); + } +} + .card__success-msg { border-left: 2px solid var(--success-msg-border); color: var(--success-msg-color); diff --git a/src/renderer/scss/component/_content.scss b/src/renderer/scss/component/_content.scss index 4a245129a..d2daf88d8 100644 --- a/src/renderer/scss/component/_content.scss +++ b/src/renderer/scss/component/_content.scss @@ -1,3 +1,8 @@ +.content__wrapper { + max-width: var(--card-max-width); + flex: 1 0 var(--file-page-min-width); +} + .content__embedded { background-color: var(--color-black); width: 100%; diff --git a/src/renderer/scss/component/_file-list.scss b/src/renderer/scss/component/_file-list.scss index c7e21cc8d..b4ed9e7ac 100644 --- a/src/renderer/scss/component/_file-list.scss +++ b/src/renderer/scss/component/_file-list.scss @@ -22,11 +22,11 @@ .file-tile { display: flex; - margin-top: $spacing-vertical; + padding-top: $spacing-vertical; .card__media { - height: var(--file-tile--media-height); - flex: 0 0 var(--file-tile--media-width); + height: var(--file-tile-media-height); + flex: 0 0 var(--file-tile-media-width); } .card__subtitle { @@ -34,8 +34,13 @@ } } -.file-tile--fullwidth { - max-width: none; +.file-tile.file-tile--small { + padding-top: $spacing-vertical * 2/3; + + .card__media { + height: var(--file-tile-media-height-small); + flex: 0 0 var(--file-tile-media-width-small); + } } .file-tile__info { diff --git a/src/renderer/scss/component/_form-field.scss b/src/renderer/scss/component/_form-field.scss index 1c8db8db9..f27667ec2 100644 --- a/src/renderer/scss/component/_form-field.scss +++ b/src/renderer/scss/component/_form-field.scss @@ -51,6 +51,10 @@ width: 100%; } +.form-field__input.form-field--first-item { + padding: 0; +} + .form-field__input { display: flex; padding-top: $spacing-vertical / 3; diff --git a/src/renderer/scss/component/_header.scss b/src/renderer/scss/component/_header.scss index 32058ec7c..1f9ab038a 100644 --- a/src/renderer/scss/component/_header.scss +++ b/src/renderer/scss/component/_header.scss @@ -6,9 +6,13 @@ z-index: 1; justify-content: space-between; align-items: center; - padding: 0 $spacing-width; + padding: 0 $spacing-width * 1/3; background-color: var(--color-bg); box-shadow: var(--box-shadow-header); + + @media (min-width: $medium-breakpoint) { + padding: 0 $spacing-width; + } } .header__navigation { diff --git a/src/renderer/scss/component/_nav.scss b/src/renderer/scss/component/_nav.scss index 8dc4587a4..fb1162c9a 100644 --- a/src/renderer/scss/component/_nav.scss +++ b/src/renderer/scss/component/_nav.scss @@ -1,7 +1,7 @@ .nav { width: var(--side-nav-width); background-color: var(--nav-bg-color); - padding: $spacing-width; + padding: $spacing-width * 1/3; color: var(--nav-color); hr { @@ -11,8 +11,13 @@ margin: $spacing-vertical $spacing-vertical * 2/3; } + @media (min-width: $medium-breakpoint) { + padding-left: $spacing-width; + width: calc(var(--side-nav-width) * 1.2); + } + @media (min-width: $large-breakpoint) { - width: calc(var(--side-nav-width) * 1.1); + width: calc(var(--side-nav-width) * 1.4); } } diff --git a/static/img/broken.png b/static/img/broken.png new file mode 100644 index 000000000..f41613f8e Binary files /dev/null and b/static/img/broken.png differ