diff --git a/.prettierignore b/.prettierignore index cec9064c3..46bfc9b46 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1 +1 @@ -src/ui/scss/component/_load-screen.scss +src/ui/scss/component/_splash.scss diff --git a/build/downloadDaemon.js b/build/downloadDaemon.js index b8221e632..878272343 100644 --- a/build/downloadDaemon.js +++ b/build/downloadDaemon.js @@ -24,14 +24,13 @@ const downloadDaemon = targetPlatform => const daemonFilePath = path.join(daemonDir, daemonFileName); const daemonVersionPath = path.join(__dirname, 'daemon.ver'); const tmpZipPath = path.join(__dirname, '..', 'dist', 'daemon.zip'); - const daemonURL = daemonURLTemplate - .replace(/DAEMONVER/g, daemonVersion) - .replace(/OSNAME/g, daemonPlatform); + const daemonURL = daemonURLTemplate.replace(/DAEMONVER/g, daemonVersion).replace(/OSNAME/g, daemonPlatform); // If a daemon and daemon.ver exists, check to see if it matches the current daemon version const hasDaemonDownloaded = fs.existsSync(daemonFilePath); const hasDaemonVersion = fs.existsSync(daemonVersionPath); let downloadedDaemonVersion; + if (hasDaemonVersion) { downloadedDaemonVersion = fs.readFileSync(daemonVersionPath, 'utf8'); } @@ -65,6 +64,7 @@ const downloadDaemon = targetPlatform => }) ) .then(() => del(`${daemonFilePath}*`)) + .then() .then(() => decompress(tmpZipPath, daemonDir, { filter: file => path.basename(file.path) === daemonFileName, @@ -80,9 +80,7 @@ const downloadDaemon = targetPlatform => resolve('Done'); }) .catch(error => { - console.error( - `\x1b[31merror\x1b[0m Daemon download failed due to: \x1b[35m${error}\x1b[0m` - ); + console.error(`\x1b[31merror\x1b[0m Daemon download failed due to: \x1b[35m${error}\x1b[0m`); reject(error); }); } diff --git a/package.json b/package.json index c19c2f56a..43448d283 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,7 @@ "copy-webpack-plugin": "^4.6.0", "country-data": "^0.0.31", "cross-env": "^5.2.0", + "css-doodle": "^0.7.1", "css-loader": "^2.1.0", "cssnano": "^4.1.10", "dat.gui": "^0.7.2", diff --git a/src/platforms/electron/createWindow.js b/src/platforms/electron/createWindow.js index 584e6d536..90fd4df29 100644 --- a/src/platforms/electron/createWindow.js +++ b/src/platforms/electron/createWindow.js @@ -16,7 +16,7 @@ export default appState => { }); const windowConfiguration = { - backgroundColor: '#2f9176', + backgroundColor: '#270f34', // Located in src/scss/init/_vars.scss `--color-background` minWidth: 950, minHeight: 600, autoHideMenuBar: true, diff --git a/src/ui/component/splash/internal/load-screen.jsx b/src/ui/component/splash/internal/load-screen.jsx deleted file mode 100644 index ca8fd95cd..000000000 --- a/src/ui/component/splash/internal/load-screen.jsx +++ /dev/null @@ -1,36 +0,0 @@ -// @flow -import * as ICONS from 'constants/icons'; -import React, { Fragment } from 'react'; -import Icon from 'component/common/icon'; -import Spinner from 'component/spinner'; -import Button from 'component/button'; -// import Doodle from 'component/doodle'; -import 'css-doodle'; - -type Props = { - message: string, - details: ?string, - isWarning: boolean, - error: boolean, -}; - -// const FancyDoodle = Doodle``; // this looks dumb but it prevents repetition from `_load-screen.scss` - -class LoadScreen extends React.PureComponent { - static defaultProps = { - isWarning: false, - }; - - render() { - const { details, message, isWarning, error } = this.props; - - return ( -
-

{__('LBRY')}

- -
- ); - } -} - -export default LoadScreen; diff --git a/src/ui/component/splash/view.jsx b/src/ui/component/splash/view.jsx index 34b5116e6..be7eb0d37 100644 --- a/src/ui/component/splash/view.jsx +++ b/src/ui/component/splash/view.jsx @@ -1,14 +1,15 @@ // @flow -import * as React from 'react'; import * as MODALS from 'constants/modal_types'; +import React from 'react'; import { Lbry } from 'lbry-redux'; +import Button from 'component/button'; import ModalWalletUnlock from 'modal/modalWalletUnlock'; import ModalIncompatibleDaemon from 'modal/modalIncompatibleDaemon'; import ModalUpgrade from 'modal/modalUpgrade'; import ModalDownloading from 'modal/modalDownloading'; -import LoadScreen from './internal/load-screen'; +import 'css-doodle'; -const ONE_MINUTE = 60 * 1000; +const FORTY_FIVE_SECONDS = 45 * 1000; type Props = { checkDaemonVersion: () => Promise, @@ -87,7 +88,7 @@ export default class SplashScreen extends React.PureComponent { // If nothing changes after 1 minute, show the error message. this.timeout = setTimeout(() => { this.setState({ error: true }); - }, ONE_MINUTE); + }, FORTY_FIVE_SECONDS); } updateStatus() { @@ -170,14 +171,14 @@ export default class SplashScreen extends React.PureComponent { const { daemonVersionMatched, onReadyToLaunch } = this.props; const { isRunning, launchWithIncompatibleDaemon } = this.state; - // if (daemonVersionMatched) { - // onReadyToLaunch(); - // } else if (launchWithIncompatibleDaemon && isRunning) { - // // The user may have decided to run the app with mismatched daemons - // // They could make this decision before the daemon is finished starting up - // // If it isn't running, this function will be called after the daemon is started - // onReadyToLaunch(); - // } + if (daemonVersionMatched) { + onReadyToLaunch(); + } else if (launchWithIncompatibleDaemon && isRunning) { + // The user may have decided to run the app with mismatched daemons + // They could make this decision before the daemon is finished starting up + // If it isn't running, this function will be called after the daemon is started + onReadyToLaunch(); + } } hasRecordedUser: boolean; @@ -206,16 +207,32 @@ export default class SplashScreen extends React.PureComponent { } render() { - const { message, details, error } = this.state; + const { error } = this.state; return ( - - +
+ +

LBRY

+ {error && ( +
+

{__('Uh oh. The flux in our Retro Encabulator must be out of whack. Try refreshing to fix it.')}

+
+
+
+

{__('If you still have issues, your anti-virus software or firewall may be preventing startup.')}

+

+ {__('Reach out to hello@lbry.com for help, or check out')}{' '} +

+
+ )} {/* Temp hack: don't show any modals on splash screen daemon is running; daemon doesn't let you quit during startup, so the "Quit" buttons - in the modals won't work. */} + in the modals won't work. */} {this.renderModals()} - +
); } } diff --git a/src/ui/scss/all.scss b/src/ui/scss/all.scss index bd7a12ae3..5088d6a1b 100644 --- a/src/ui/scss/all.scss +++ b/src/ui/scss/all.scss @@ -24,7 +24,6 @@ @import 'component/header'; @import 'component/icon'; @import 'component/item-list'; -@import 'component/load-screen'; @import 'component/main'; @import 'component/markdown-editor'; @import 'component/markdown-preview'; @@ -38,6 +37,7 @@ @import 'component/search'; @import 'component/snack-bar'; @import 'component/spinner'; +@import 'component/splash'; @import 'component/subscriptions'; @import 'component/syntax-highlighter'; @import 'component/table'; diff --git a/src/ui/scss/component/_load-screen.scss b/src/ui/scss/component/_load-screen.scss deleted file mode 100644 index 79aeb6f44..000000000 --- a/src/ui/scss/component/_load-screen.scss +++ /dev/null @@ -1,130 +0,0 @@ -.load-screen { - width: 100vw; - height: 100vh; - - align-items: center; - background-color: #270f34; - display: flex; - justify-content: center; - overflow: hidden; - - css-doodle { - --color: @p(var(--lbry-teal-1), var(--lbry-orange-1), var(--lbry-cyan-3), var(--lbry-pink-5)); - --rule: ( - :doodle { - @grid: 30x1 / 18vmin; - --deg: @p(-180deg, 180deg); - } - :container { - perspective: 30vmin; - } - :after, :before { - // content: ''; - // background: var(--color); - // @place-cell: @r(100%) @r(100%); - // @size: @r(6px); - // @shape: heart; - } - - @place-cell: center; - @size: 100%; - - box-shadow: @m2(0 0 50px var(--color)); - background: @m100( - radial-gradient(var(--color) 50%, transparent 0) - @r(-20%, 120%) @r(-20%, 100%) / 1px 1px - no-repeat - ); - - will-change: transform, opacity; - animation: scale-up 12s linear infinite; - animation-delay: calc(-12s / @size() * @i()); - - @keyframes scale-up { - 0%, 95.01%, 100% { - transform: translateZ(0) rotate(0); - opacity: 0; - } - 10% { - opacity: 1; - } - 95% { - transform: - translateZ(35vmin) rotateZ(@var(--deg)); - } - } - ) - } -} - -// .load-screen__actions { -// font-size: 1.2em; -// margin-top: var(--spacing-vertical-medium); -// } - -// .load-screen__button { -// border-bottom: 1px solid $lbry-white; -// color: $lbry-white; -// transition: none; - -// &:hover { -// border-bottom: 1px solid $lbry-blue-1; -// color: $lbry-blue-1; -// } -// } - -// .load-screen__details { -// font-weight: 600; -// line-height: 1; -// max-width: 400px; -// } - -.load-screen__header { - display: flex; - justify-content: center; - margin-bottom: var(--spacing-vertical-medium); -} - -.load-screen__overlay { - // @include center; - - color: $lbry-white; - flex-direction: column; - align-items: center; - justify-content: center; - position: relative; - text-align: center; - z-index: 1; -} - -.load-screen__title { - font-size: 40px; - font-weight: 700; - line-height: 1; - position: relative; - color: $lbry-white; - position: absolute; - - // sup { - // margin-left: -var(--spacing-vertical-tiny); - // padding: var(--spacing-vertical-miniscule) var(--spacing-vertical-small); - - // background-color: rgba($lbry-white, 0.3); - // border-radius: 0.2rem; - // color: $lbry-white; - // font-size: 0.6rem; - // font-weight: 400; - // letter-spacing: 0.1rem; - // line-height: 1; - // position: absolute; - // text-transform: uppercase; - // top: 1.5rem; - // } -} - - - -// .load-screen--help { -// font-size: 14px; -// padding-top: $spacing-vertical; -// } diff --git a/src/ui/scss/component/_modal.scss b/src/ui/scss/component/_modal.scss index c90961be2..c971123b0 100644 --- a/src/ui/scss/component/_modal.scss +++ b/src/ui/scss/component/_modal.scss @@ -90,8 +90,7 @@ .error-modal__content { display: flex; - padding: 0 var(--spacing-vertical-medium) var(--spacing-vertical-medium) - var(--spacing-vertical-medium); + padding: 0 var(--spacing-vertical-medium) var(--spacing-vertical-medium) var(--spacing-vertical-medium); } .error-modal__warning-symbol { diff --git a/src/ui/scss/component/_splash.scss b/src/ui/scss/component/_splash.scss new file mode 100644 index 000000000..5d61642ff --- /dev/null +++ b/src/ui/scss/component/_splash.scss @@ -0,0 +1,91 @@ +// +// Formatting is ignored for this file because css-doodle requires that the styles be in a specific shape +// +.splash { + width: 100vw; + height: 100vh; + + align-items: center; + background-color: var(--color-background); + display: flex; + justify-content: center; + overflow: hidden; + + css-doodle { + z-index: 0; + + --color: @p(var(--lbry-teal-1), var(--lbry-orange-1), var(--lbry-cyan-3), var(--lbry-pink-5)); + --rule: ( + :doodle { + @grid: 30x1 / 18vmin; + --deg: @p(-180deg, 180deg); + } + :container { + perspective: 30vmin; + } + + @place-cell: center; + @size: 100%; + + box-shadow: @m2(0 0 50px var(--color)); + background: @m100( + radial-gradient(var(--color) 50%, transparent 0) + @r(-20%, 120%) @r(-20%, 100%) / 1px 1px + no-repeat + ); + + will-change: transform, opacity; + animation: scale-up 12s linear infinite; + animation-delay: calc(-12s / @size() * @i()); + + @keyframes scale-up { + 0%, 95.01%, 100% { + transform: translateZ(0) rotate(0); + opacity: 0; + } + 10% { + opacity: 1; + } + 95% { + transform: + translateZ(35vmin) rotateZ(@var(--deg)); + } + } + ) + } +} + +.splash__actions { + margin-top: var(--spacing-vertical-medium); +} + +.splash__button { + border-bottom: 1px solid $lbry-white; + color: $lbry-white; + transition: none; + + &:hover { + border-bottom: 1px solid $lbry-blue-1; + color: $lbry-blue-1; + } +} + +.splash__details { + font-weight: 600; + line-height: 1; + max-width: 400px; +} + +.splash__title { + position: absolute; + font-size: 40px; + line-height: 1; + font-weight: 700; + color: $lbry-white; +} + +.splash__error { + position: absolute; + margin-top: 25rem; + box-shadow: var(--card-box-shadow) $lbry-gray-5; +} \ No newline at end of file diff --git a/src/ui/scss/init/_vars.scss b/src/ui/scss/init/_vars.scss index ae5a3129e..1bdebafab 100644 --- a/src/ui/scss/init/_vars.scss +++ b/src/ui/scss/init/_vars.scss @@ -9,7 +9,6 @@ $large-breakpoint: 1921px; // Width & spacing --side-nav-width: 180px; --font-size-subtext-multiple: 0.92; - --spacing-vertical-miniscule: calc(2rem / 5); --spacing-vertical-tiny: calc(2rem / 4); --spacing-vertical-small: calc(2rem / 3); @@ -17,15 +16,15 @@ $large-breakpoint: 1921px; --spacing-vertical-large: 2rem; --spacing-vertical-xlarge: 3rem; --spacing-main-padding: var(--spacing-vertical-xlarge); - --file-page-max-width: 1787px; --file-max-height: 788px; --file-max-width: 1400px; - --video-aspect-ratio: 56.25%; // 9 x 16 - --channel-thumbnail-size: 10rem; + // Color + --color-background: #270f34; + // Text --text-max-width: 660px; --text-link-padding: 4px; diff --git a/yarn.lock b/yarn.lock index 9d3cb337d..fc556c0eb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3001,6 +3001,11 @@ css-declaration-sorter@^4.0.1: postcss "^7.0.1" timsort "^0.3.0" +css-doodle@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/css-doodle/-/css-doodle-0.7.1.tgz#477466310df6554ec5182349745194ba37415670" + integrity sha512-TRs+7YLgP/yc0EdrL5Us2GRHbhIgf4GsQWAt5WdRxr5pwwpWl8Q9jZle431Z/5u5C29jiEoItjIaKE84xFh+kA== + css-hot-loader@^1.4.3: version "1.4.4" resolved "https://registry.yarnpkg.com/css-hot-loader/-/css-hot-loader-1.4.4.tgz#ae784932cd8b7d092f7f15702af08b3ec9436052"