From 5b84d07fec760e0502904c3e802f4de93814bc04 Mon Sep 17 00:00:00 2001 From: Franco Montenegro Date: Mon, 1 Mar 2021 14:28:05 -0300 Subject: [PATCH 1/6] Release date -- initial attempt (squashed and rebased) - Use white color for calendar buttons in release date input - Update icon color for release date input - Allow to set time in release date and display it under additional options - Add release date field --- package.json | 1 + .../publishAdditionalOptions/view.jsx | 10 +- ui/component/publishReleaseDate/index.js | 13 ++ ui/component/publishReleaseDate/view.jsx | 38 ++++++ ui/modal/modalPublishPreview/view.jsx | 4 + ui/scss/component/_card.scss | 5 + ui/scss/component/_form-field.scss | 54 ++++++++- yarn.lock | 114 ++++++++++++++++++ 8 files changed, 235 insertions(+), 4 deletions(-) create mode 100644 ui/component/publishReleaseDate/index.js create mode 100644 ui/component/publishReleaseDate/view.jsx diff --git a/package.json b/package.json index 92a05dcac..186c8fb8b 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "electron-updater": "^4.2.4", "express": "^4.17.1", "if-env": "^1.0.4", + "react-datetime-picker": "^3.1.0", "remove-markdown": "^0.3.0", "tempy": "^0.6.0", "videojs-logo": "^2.1.4" diff --git a/ui/component/publishAdditionalOptions/view.jsx b/ui/component/publishAdditionalOptions/view.jsx index b4ae97105..8e05b04cc 100644 --- a/ui/component/publishAdditionalOptions/view.jsx +++ b/ui/component/publishAdditionalOptions/view.jsx @@ -4,6 +4,7 @@ import classnames from 'classnames'; import usePersistedState from 'effects/use-persisted-state'; import { FormField } from 'component/common/form'; import Button from 'component/button'; +import PublishReleaseDate from 'component/publishReleaseDate'; import LicenseType from './license-type'; import Card from 'component/common/card'; import SUPPORTED_LANGUAGES from 'constants/supported_languages'; @@ -111,6 +112,7 @@ function PublishAdditionalOptions(props: Props) { return ( {!hideSection && ( @@ -151,12 +153,14 @@ function PublishAdditionalOptions(props: Props) { )} */} {/* @endif */}
+ + updatePublishForm({ language: event.target.value })} + onChange={(event) => updatePublishForm({ language: event.target.value })} > {Object.entries(SUPPORTED_LANGUAGES).map(([langkey, langName]) => ( // $FlowFixMe @@ -176,12 +180,12 @@ function PublishAdditionalOptions(props: Props) { licenseUrl: newLicenseUrl, }) } - handleLicenseDescriptionChange={event => + handleLicenseDescriptionChange={(event) => updatePublishForm({ otherLicenseDescription: event.target.value, }) } - handleLicenseUrlChange={event => updatePublishForm({ licenseUrl: event.target.value })} + handleLicenseUrlChange={(event) => updatePublishForm({ licenseUrl: event.target.value })} />
diff --git a/ui/component/publishReleaseDate/index.js b/ui/component/publishReleaseDate/index.js new file mode 100644 index 000000000..b51dd4e7c --- /dev/null +++ b/ui/component/publishReleaseDate/index.js @@ -0,0 +1,13 @@ +import { connect } from 'react-redux'; +import { doUpdatePublishForm, makeSelectPublishFormValue } from 'lbry-redux'; +import PublishReleaseDate from './view'; + +const select = (state) => ({ + releaseTime: makeSelectPublishFormValue('release_time')(state), +}); + +const perform = (dispatch) => ({ + updatePublishForm: (value) => dispatch(doUpdatePublishForm(value)), +}); + +export default connect(select, perform)(PublishReleaseDate); diff --git a/ui/component/publishReleaseDate/view.jsx b/ui/component/publishReleaseDate/view.jsx new file mode 100644 index 000000000..d475015f2 --- /dev/null +++ b/ui/component/publishReleaseDate/view.jsx @@ -0,0 +1,38 @@ +// @flow +import React, { useCallback } from 'react'; +import DateTimePicker from 'react-datetime-picker'; + +type Props = { + releaseTime: ?number, + updatePublishForm: ({}) => void, +}; + +const PublishReleaseDate = (props: Props) => { + const { releaseTime, updatePublishForm } = props; + const maxDate = new Date(); + + const dateOrToday = useCallback((value) => { + return value ? new Date(value) : new Date(); + }, []); + + const onChange = useCallback((value) => { + updatePublishForm({ release_time: dateOrToday(value) }); + }, []); + + return ( +
+ + +
+ ); +}; + +export default PublishReleaseDate; diff --git a/ui/modal/modalPublishPreview/view.jsx b/ui/modal/modalPublishPreview/view.jsx index 336e9a018..f5024c309 100644 --- a/ui/modal/modalPublishPreview/view.jsx +++ b/ui/modal/modalPublishPreview/view.jsx @@ -1,5 +1,6 @@ // @flow import React from 'react'; +import moment from 'moment'; import Button from 'component/button'; import { Form, FormField } from 'component/common/form'; import { Modal } from 'modal/modal'; @@ -28,6 +29,7 @@ type Props = { currency: string, }, language: string, + release_time: ?string, licenseType: string, otherLicenseDescription: ?string, licenseUrl: ?string, @@ -61,6 +63,7 @@ const ModalPublishPreview = (props: Props) => { contentIsFree, fee, language, + release_time, licenseType, otherLicenseDescription, licenseUrl, @@ -227,6 +230,7 @@ const ModalPublishPreview = (props: Props) => { {createRow(__('Deposit'), depositValue)} {createRow(__('Price'), priceValue)} {createRow(__('Language'), language)} + {createRow(__('Release Date'), moment(release_time).format('MMMM Do, YYYY - h:mm a'))} {createRow(__('License'), licenseValue)} {createRow(__('Tags'), tagsValue)} diff --git a/ui/scss/component/_card.scss b/ui/scss/component/_card.scss index ca80f8d00..5924dd989 100644 --- a/ui/scss/component/_card.scss +++ b/ui/scss/component/_card.scss @@ -10,6 +10,11 @@ } } +.card--enable-overflow { + overflow: visible; + margin-bottom: var(--spacing-m); +} + .card--disabled { opacity: 0.3; pointer-events: none; diff --git a/ui/scss/component/_form-field.scss b/ui/scss/component/_form-field.scss index cb3103133..794a8ce13 100644 --- a/ui/scss/component/_form-field.scss +++ b/ui/scss/component/_form-field.scss @@ -2,7 +2,8 @@ input, textarea, -select { +select, +.date-picker-input { height: var(--height-input); border-radius: var(--border-radius); border: 1px solid; @@ -485,3 +486,54 @@ fieldset-section { #automatic_dark_mode_range_end { min-width: 6em; } + +.date-picker-input { + font-weight: bold; + + .react-datetime-picker__wrapper { + border: 0; + } +} + +.form-field-date-picker { + margin-bottom: var(--spacing-l); +} + +.form-field-date-picker-label { + display: block; +} + +.form-field-calendar { + border-radius: var(--card-radius); + border: 1px solid var(--color-border); +} + +.react-datetime-picker__button { + svg { + stroke: var(--color-black); + } +} + +[theme='dark'] { + .react-datetime-picker__button { + svg { + stroke: var(--color-white); + } + } +} + +.react-date-picker__calendar { + z-index: 1000; +} + +.react-calendar__tile--now, +.react-calendar__tile--now:enabled:hover, +.react-calendar__tile--now:enabled:focus { + background: var(--color-primary-alt); +} + +.react-calendar__tile--active, +.react-calendar__tile--active:enabled:hover, +.react-calendar__tile--active:enabled:focus { + background: var(--color-primary); +} diff --git a/yarn.lock b/yarn.lock index e7f413130..38d537ab9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1708,6 +1708,11 @@ version "1.5.2" resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" +"@types/react-calendar@^3.0.0": + version "3.1.3" + resolved "https://registry.yarnpkg.com/@types/react-calendar/-/react-calendar-3.1.3.tgz#bd0947c28738f6419649be22d80624b05fde2fb9" + integrity sha512-4kvDfKta9bNnuRieuGYPxdDlh3UqRUKE8+fMbmZGk0Z/MdUGHupxXwPCWLbVH7FZU48o4bhT+XX8rfZrexdnAw== + "@types/semver@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.1.0.tgz#c8c630d4c18cd326beff77404887596f96408408" @@ -1951,6 +1956,11 @@ "@webassemblyjs/wast-parser" "1.8.5" "@xtuc/long" "4.2.2" +"@wojtekmaj/date-utils@^1.0.0", "@wojtekmaj/date-utils@^1.0.2", "@wojtekmaj/date-utils@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@wojtekmaj/date-utils/-/date-utils-1.0.3.tgz#2dcfd92881425c5923e429c2aec86fb3609032a1" + integrity sha512-1VPkkTBk07gMR1fjpBtse4G+oJqpmE+0gUFB0dg3VIL7qJmUVaBoD/vlzMm/jNeOPfvlmerl1lpnsZyBUFIRuw== + "@xtuc/ieee754@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" @@ -3972,6 +3982,11 @@ destroy@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" +detect-element-overflow@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/detect-element-overflow/-/detect-element-overflow-1.2.0.tgz#86e504292ffedc3aef813395fbdf0261aaf6afa9" + integrity sha512-Jtr9ivYPhpd9OJux+hjL0QjUKiS1Ghgy8tvIufUjFslQgIWvgGr4mn57H190APbKkiOmXnmtMI6ytaKzMusecg== + detect-file@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" @@ -5479,6 +5494,13 @@ get-stream@^5.1.0: dependencies: pump "^3.0.0" +get-user-locale@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/get-user-locale/-/get-user-locale-1.4.0.tgz#a2c4b5da46feec9f03c9b07d197b1620490a5370" + integrity sha512-gQo03lP1OArHLKlnoglqrGGl7b04u2EP9Xutmp72cMdtrrSD7ZgIsCsUKZynYWLDkVJW33Cj3pliP7uP0UonHQ== + dependencies: + lodash.once "^4.1.1" + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -7179,6 +7201,11 @@ lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" +lodash.once@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= + lodash.pickby@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.pickby/-/lodash.pickby-4.6.0.tgz#7dea21d8c18d7703a27c704c15d3b84a67e33aff" @@ -7343,6 +7370,11 @@ make-dir@^3.0.2: dependencies: semver "^6.0.0" +make-event-props@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/make-event-props/-/make-event-props-1.2.0.tgz#96b87d88919533b8f8934b58b4c3d5679459a0cf" + integrity sha512-BmWFkm/jZzVH9A0tEBdkjAARUz/eha+5IRyfOndeSMKRadkgR5DawoBHoRwLxkYmjJOI5bHkXKpaZocxj+dKgg== + mamacro@^0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" @@ -7499,6 +7531,11 @@ memory-fs@^0.5.0: errno "^0.1.3" readable-stream "^2.0.1" +merge-class-names@^1.1.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/merge-class-names/-/merge-class-names-1.4.0.tgz#02edcdd5ff677fbb03b47ecd4586df89d697b81b" + integrity sha512-xNdBM7s+6uD+vNZJEymqrFbMBCDGzoA8clZTcj2F1XIy1QQKF+wjFVv7iDZFfdCBnViTdt54A4Ye2lmBsXrBjQ== + merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" @@ -9209,6 +9246,25 @@ react-awesome-lightbox@^1.7.3: resolved "https://registry.yarnpkg.com/react-awesome-lightbox/-/react-awesome-lightbox-1.7.3.tgz#ee1c00fd4197e0e65bf996aa219eac4d8b6db5a0" integrity sha512-mSxdL3KGzuh2eR8I00nv9njiolmMoXITuCvfd71DBXK13JW3e+Z/sCMENS9+dngBJU8/m7dR1Ix0W6afS5cFsA== +react-calendar@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/react-calendar/-/react-calendar-3.3.1.tgz#da691a5d59c88f178695fd8b33909a71d698021f" + integrity sha512-iDIrhE0ABz3mChAIvA+5d2UtQGEb5oaUpLiEbrRdWHBYb45MhsbO59pG9HIy2uTdHkBF/nvzRV2JBmMfdg/0Qg== + dependencies: + "@wojtekmaj/date-utils" "^1.0.2" + get-user-locale "^1.2.0" + merge-class-names "^1.1.1" + prop-types "^15.6.0" + +react-clock@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/react-clock/-/react-clock-3.0.0.tgz#0d29f8e682ef516574061d1d24b1a286cb2da89b" + integrity sha512-D3K82D3YGcDtzxZCfiACLcDTL8cJXSgpdrzTY9ff3H5vflxlLzTSLF8apZRo6JZzOFrZQvw5mrS7TkQzj9nG0A== + dependencies: + "@wojtekmaj/date-utils" "^1.0.0" + merge-class-names "^1.1.1" + prop-types "^15.6.0" + react-compound-slider@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/react-compound-slider/-/react-compound-slider-2.5.0.tgz#99771a3397f4ab00aa2a37f8410da87e6ca2449b" @@ -9225,6 +9281,37 @@ react-confetti@^4.0.1: dependencies: tween-functions "^1.2.0" +react-date-picker@^8.0.7: + version "8.0.7" + resolved "https://registry.yarnpkg.com/react-date-picker/-/react-date-picker-8.0.7.tgz#43585751feeaf2b790eea8c343c3fcb35ad95ede" + integrity sha512-ZuS9NPHUUz0zeeXlYOfq58cteHLRC94NO76ti28aN/Ybi9nugG2SfR46i/5xTL5094rRPiXJveGA1P1cJqQMsg== + dependencies: + "@types/react-calendar" "^3.0.0" + "@wojtekmaj/date-utils" "^1.0.3" + get-user-locale "^1.2.0" + make-event-props "^1.1.0" + merge-class-names "^1.1.1" + prop-types "^15.6.0" + react-calendar "^3.3.1" + react-fit "^1.0.3" + update-input-width "^1.1.1" + +react-datetime-picker@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/react-datetime-picker/-/react-datetime-picker-3.1.0.tgz#109cc062ff666948713f7b45833b323c73975619" + integrity sha512-osC97vzEEi3al9Bo+V+0+SCcDIhVVXTmSngeW4NL/yB9AsNf0ShF5tEmPKkGoSQBBW3GGthb4LOQzaOEzu+FXw== + dependencies: + "@wojtekmaj/date-utils" "^1.0.3" + get-user-locale "^1.2.0" + make-event-props "^1.1.0" + merge-class-names "^1.1.1" + prop-types "^15.6.0" + react-calendar "^3.3.1" + react-clock "^3.0.0" + react-date-picker "^8.0.7" + react-fit "^1.0.3" + react-time-picker "^4.1.0" + react-dom@^16.8.2: version "16.13.0" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.13.0.tgz#cdde54b48eb9e8a0ca1b3dc9943d9bb409b81866" @@ -9241,6 +9328,14 @@ react-draggable@^3.3.0: classnames "^2.2.5" prop-types "^15.6.0" +react-fit@^1.0.3: + version "1.3.1" + resolved "https://registry.yarnpkg.com/react-fit/-/react-fit-1.3.1.tgz#850cb5d554fdfa4b27891f62a9d290d3e7eda57b" + integrity sha512-MmVk/SXyVbxiz9peAeD7fWxFdGLoy/sCxte01M3w74regPIVkLqc2yT0wUAGRd1MNP1fQ40MqYKNBLpbK/aI1w== + dependencies: + detect-element-overflow "^1.2.0" + prop-types "^15.6.0" + react-google-recaptcha@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/react-google-recaptcha/-/react-google-recaptcha-2.0.1.tgz#3276b29659493f7ca2a5b7739f6c239293cdf1d8" @@ -9344,6 +9439,20 @@ react-spring@^8.0.20, react-spring@^8.0.27: "@babel/runtime" "^7.3.1" prop-types "^15.5.8" +react-time-picker@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/react-time-picker/-/react-time-picker-4.1.2.tgz#7e977ba546a2313d622a536494cec6e4d727b57b" + integrity sha512-O2lSyv9j11YcpVuxQnJnqanaYiJ7yyCl7/p6jS6HHcR0i+plX95Ko105CKyJeAd40I6LxHqfweR+9DIL2AFmYg== + dependencies: + "@wojtekmaj/date-utils" "^1.0.0" + get-user-locale "^1.2.0" + make-event-props "^1.1.0" + merge-class-names "^1.1.1" + prop-types "^15.6.0" + react-clock "^3.0.0" + react-fit "^1.0.3" + update-input-width "^1.1.1" + react@^16.8.2: version "16.13.0" resolved "https://registry.yarnpkg.com/react/-/react-16.13.0.tgz#d046eabcdf64e457bbeed1e792e235e1b9934cf7" @@ -11331,6 +11440,11 @@ upath@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" +update-input-width@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/update-input-width/-/update-input-width-1.2.1.tgz#769d6182413590c3b50b52ffa9c65d79e2c17f95" + integrity sha512-zygDshqDb2C2/kgfoD423n5htv/3OBF7aTaz2u2zZy998EJki8njOHOeZjKEd8XSYeDziIX1JXfMsKaIRJeJ/Q== + update-notifier@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" -- 2.45.2 From cdb2246d3c212443851fee9df4b84e0c3c65a5d3 Mon Sep 17 00:00:00 2001 From: infinite-persistence Date: Thu, 29 Apr 2021 23:07:58 +0800 Subject: [PATCH 2/6] Upgrade to latest react-datetime-picker. I believe this also picks up the y18n security fix. --- package.json | 2 +- yarn.lock | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 186c8fb8b..3d12baa41 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "electron-updater": "^4.2.4", "express": "^4.17.1", "if-env": "^1.0.4", - "react-datetime-picker": "^3.1.0", + "react-datetime-picker": "^3.2.1", "remove-markdown": "^0.3.0", "tempy": "^0.6.0", "videojs-logo": "^2.1.4" diff --git a/yarn.lock b/yarn.lock index 38d537ab9..3ef3e97a3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9281,10 +9281,10 @@ react-confetti@^4.0.1: dependencies: tween-functions "^1.2.0" -react-date-picker@^8.0.7: - version "8.0.7" - resolved "https://registry.yarnpkg.com/react-date-picker/-/react-date-picker-8.0.7.tgz#43585751feeaf2b790eea8c343c3fcb35ad95ede" - integrity sha512-ZuS9NPHUUz0zeeXlYOfq58cteHLRC94NO76ti28aN/Ybi9nugG2SfR46i/5xTL5094rRPiXJveGA1P1cJqQMsg== +react-date-picker@^8.1.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/react-date-picker/-/react-date-picker-8.1.1.tgz#1959608cd042c9bfcf2faa6d63a56e9ef6b17e2b" + integrity sha512-kFhn+uSJML+EuROvR6qLYU5G3wsxrdB2K1ugh1t6HjJCjphE6ot85jb8THWebqWEcQi07pLseU7ZFpzKDD3A6A== dependencies: "@types/react-calendar" "^3.0.0" "@wojtekmaj/date-utils" "^1.0.3" @@ -9296,10 +9296,10 @@ react-date-picker@^8.0.7: react-fit "^1.0.3" update-input-width "^1.1.1" -react-datetime-picker@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/react-datetime-picker/-/react-datetime-picker-3.1.0.tgz#109cc062ff666948713f7b45833b323c73975619" - integrity sha512-osC97vzEEi3al9Bo+V+0+SCcDIhVVXTmSngeW4NL/yB9AsNf0ShF5tEmPKkGoSQBBW3GGthb4LOQzaOEzu+FXw== +react-datetime-picker@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/react-datetime-picker/-/react-datetime-picker-3.2.1.tgz#d3a9631bcba17bd0047e6424cff0dfe242d9cf0e" + integrity sha512-elybaAL7RJG7r0elYZze5/zQo1ds0v+v89tyZkzEShw+6I1EcveXwYPOMj3aq0k7D5kY/K+dC5dWYw0w4d9kmw== dependencies: "@wojtekmaj/date-utils" "^1.0.3" get-user-locale "^1.2.0" @@ -9308,9 +9308,9 @@ react-datetime-picker@^3.1.0: prop-types "^15.6.0" react-calendar "^3.3.1" react-clock "^3.0.0" - react-date-picker "^8.0.7" + react-date-picker "^8.1.0" react-fit "^1.0.3" - react-time-picker "^4.1.0" + react-time-picker "^4.2.0" react-dom@^16.8.2: version "16.13.0" @@ -9439,10 +9439,10 @@ react-spring@^8.0.20, react-spring@^8.0.27: "@babel/runtime" "^7.3.1" prop-types "^15.5.8" -react-time-picker@^4.1.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/react-time-picker/-/react-time-picker-4.1.2.tgz#7e977ba546a2313d622a536494cec6e4d727b57b" - integrity sha512-O2lSyv9j11YcpVuxQnJnqanaYiJ7yyCl7/p6jS6HHcR0i+plX95Ko105CKyJeAd40I6LxHqfweR+9DIL2AFmYg== +react-time-picker@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/react-time-picker/-/react-time-picker-4.2.1.tgz#b27f0bbc2e58534f20dbf10b14d0b8f3334fcb07" + integrity sha512-T0aEabJ3bz54l8LV3pdpB5lOZuO3pRIbry5STcUV58UndlrWLcHpdpvS1IC8JLNXhbLxzGs1MmpASb5k1ddlsg== dependencies: "@wojtekmaj/date-utils" "^1.0.0" get-user-locale "^1.2.0" -- 2.45.2 From 1d0eb9b81ad77ebd3f78c035bb57078459a84a62 Mon Sep 17 00:00:00 2001 From: infinite-persistence Date: Fri, 30 Apr 2021 12:04:58 +0800 Subject: [PATCH 3/6] Handle dark theme and general style fixes. --- ui/component/publishReleaseDate/view.jsx | 2 +- ui/scss/component/_form-field.scss | 230 +++++++++++++++++++---- 2 files changed, 197 insertions(+), 35 deletions(-) diff --git a/ui/component/publishReleaseDate/view.jsx b/ui/component/publishReleaseDate/view.jsx index d475015f2..d1a738588 100644 --- a/ui/component/publishReleaseDate/view.jsx +++ b/ui/component/publishReleaseDate/view.jsx @@ -21,7 +21,7 @@ const PublishReleaseDate = (props: Props) => { return (
- + * { + width: 50%; + margin: 0.5em; + } + + .react-calendar, + .react-calendar *, + .react-calendar *:before, + .react-calendar *:after { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + padding: 2px 1px; + } + + .react-calendar button { + margin: 0; + border: 0; + outline: none; + } + + .react-calendar button:enabled:hover { + cursor: pointer; + } + + .react-calendar__navigation { + height: 44px; + margin-bottom: 1em; + color: var(--color-text); + } + + .react-calendar__navigation__label { + color: var(--color-text); + } + + .react-calendar__navigation button { + min-width: 44px; + background: none; + color: var(--color-text); + } + + .react-calendar__navigation button:enabled:hover, + .react-calendar__navigation button:enabled:focus { + background: var(--color-button-alt-bg-hover); + } + + .react-calendar__navigation button[disabled] { + color: var(--color-text); + } + + .react-calendar__month-view__weekdays { + text-align: center; + text-transform: uppercase; + font-weight: bold; + font-size: 0.75em; + color: var(--color-text-alt); + } + + .react-calendar__month-view__weekdays__weekday { + padding: 0.5em; + } + + .react-calendar__month-view__weekNumbers { + font-weight: bold; + } + + .react-calendar__month-view__weekNumbers .react-calendar__tile { + display: flex; + align-items: center; + justify-content: center; + font-size: 0.75em; + padding: calc(0.75em / 0.75) calc(0.5em / 0.75); + } + + .react-calendar__month-view__days__day, + .react-calendar__month-view__days__day--weekend { + color: var(--color-text); + font-weight: normal; + } + + .react-calendar__month-view__days__day--neighboringMonth { + color: var(--color-gray-5); + } + + .react-calendar__year-view .react-calendar__tile, + .react-calendar__decade-view .react-calendar__tile, + .react-calendar__century-view .react-calendar__tile { + padding: 2em 0.5em; + } + + .react-calendar__tile { + max-width: 100%; + text-align: center; + padding: 0.75em 0.5em; + background: none; + border-radius: var(--border-radius); + color: var(--color-text); + } + + .react-calendar__tile:enabled:hover, + .react-calendar__tile:enabled:focus { + background: var(--color-button-alt-bg-hover); + } + + .react-calendar__tile--now { + background: var(--color-button-secondary-bg); + } + + .react-calendar__tile--now:enabled:hover, + .react-calendar__tile--now:enabled:focus { + background: var(--color-button-secondary-bg-hover); + } + + .react-calendar__tile--hasActive { + color: var(--color-button-primary-text); + background: var(--color-button-primary-bg); + } + + .react-calendar__tile--hasActive:enabled:hover, + .react-calendar__tile--hasActive:enabled:focus { + background: var(--color-button-primary-bg-hover); + } + + .react-calendar__tile--active { + color: var(--color-button-primary-text); + background: var(--color-button-primary-bg); + } + + .react-calendar__tile--active:enabled:hover, + .react-calendar__tile--active:enabled:focus { + background: var(--color-button-primary-bg-hover); + } + + .react-calendar--selectRange .react-calendar__tile--hover { + background-color: #e6e6e6; + } + + .react-datetime-picker__inputGroup__amPm { + background: var(--color-input-bg); + } + + .react-datetime-picker__inputGroup__leadingZero { + // Not perfect, but good enough for our standard zoom levels. + margin-bottom: 1px; + } + + .react-datetime-picker__inputGroup__input--hasLeadingZero { + margin-left: -0.54em; + padding-left: calc(1px + 0.54em); + } + + .react-calendar__month-view__days__day--neighboringMonth { + color: var(--color-gray-5); + } } .form-field-calendar { - border-radius: var(--card-radius); + border-radius: var(--border-radius); border: 1px solid var(--color-border); -} - -.react-datetime-picker__button { - svg { - stroke: var(--color-black); - } -} - -[theme='dark'] { - .react-datetime-picker__button { - svg { - stroke: var(--color-white); - } - } -} - -.react-date-picker__calendar { - z-index: 1000; -} - -.react-calendar__tile--now, -.react-calendar__tile--now:enabled:hover, -.react-calendar__tile--now:enabled:focus { - background: var(--color-primary-alt); -} - -.react-calendar__tile--active, -.react-calendar__tile--active:enabled:hover, -.react-calendar__tile--active:enabled:focus { - background: var(--color-primary); + margin-left: calc(var(--spacing-xs) * -1); + margin-bottom: var(--spacing-xs); + animation: menu-animate-in var(--animation-duration) var(--animation-style); + box-shadow: 3px 3px rgba(0, 0, 0, 0.1); } -- 2.45.2 From f1e349b1c086b81986ef4df5a5aec858f47789db Mon Sep 17 00:00:00 2001 From: infinite-persistence Date: Fri, 30 Apr 2021 18:25:48 +0800 Subject: [PATCH 4/6] [+redux] Change how release_time is edited. - `releaseTime` is now a number instead of a string, matching `release_time`. It was getting confusing what the variable units were. - `releaseTime` will always match `release_time` for an edit. It will be used in the GUI to reset just the date to the original, instead of having to reset the entire form. - `releaseTimeEdited` will be used by `updatePublishForm` in the GUI to represent the desired new release time. Set to `undefined` if we don't want to change the date. --- package.json | 2 +- ui/component/publishReleaseDate/index.js | 2 +- ui/component/publishReleaseDate/view.jsx | 39 ++++++++++++++++++------ ui/modal/modalPublishPreview/view.jsx | 10 ++++-- yarn.lock | 4 +-- 5 files changed, 41 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 3d12baa41..32ed3407d 100644 --- a/package.json +++ b/package.json @@ -143,7 +143,7 @@ "imagesloaded": "^4.1.4", "json-loader": "^0.5.4", "lbry-format": "https://github.com/lbryio/lbry-format.git", - "lbry-redux": "lbryio/lbry-redux#6fc11454eb1b8f9e323c234669880721f12664ee", + "lbry-redux": "lbryio/lbry-redux#35dd7650fb235109d4a7ab44d1f6dde63dfdf2f7", "lbryinc": "lbryio/lbryinc#8f9a58bfc8312a65614fd7327661cdcc502c4e59", "lint-staged": "^7.0.2", "localforage": "^1.7.1", diff --git a/ui/component/publishReleaseDate/index.js b/ui/component/publishReleaseDate/index.js index b51dd4e7c..b569fe5d2 100644 --- a/ui/component/publishReleaseDate/index.js +++ b/ui/component/publishReleaseDate/index.js @@ -3,7 +3,7 @@ import { doUpdatePublishForm, makeSelectPublishFormValue } from 'lbry-redux'; import PublishReleaseDate from './view'; const select = (state) => ({ - releaseTime: makeSelectPublishFormValue('release_time')(state), + releaseTime: makeSelectPublishFormValue('releaseTime')(state), }); const perform = (dispatch) => ({ diff --git a/ui/component/publishReleaseDate/view.jsx b/ui/component/publishReleaseDate/view.jsx index d1a738588..666481c7a 100644 --- a/ui/component/publishReleaseDate/view.jsx +++ b/ui/component/publishReleaseDate/view.jsx @@ -1,7 +1,15 @@ // @flow -import React, { useCallback } from 'react'; +import React from 'react'; import DateTimePicker from 'react-datetime-picker'; +function linuxTimestampToDate(linuxTimestamp: number) { + return new Date(linuxTimestamp * 1000); +} + +function dateToLinuxTimestamp(date: Date) { + return Number(Math.round(date.getTime() / 1000)); +} + type Props = { releaseTime: ?number, updatePublishForm: ({}) => void, @@ -10,14 +18,27 @@ type Props = { const PublishReleaseDate = (props: Props) => { const { releaseTime, updatePublishForm } = props; const maxDate = new Date(); + const [date, setDate] = React.useState(releaseTime ? linuxTimestampToDate(releaseTime) : new Date()); - const dateOrToday = useCallback((value) => { - return value ? new Date(value) : new Date(); - }, []); - - const onChange = useCallback((value) => { - updatePublishForm({ release_time: dateOrToday(value) }); - }, []); + const onChange = (value) => { + if (!value) { + if (releaseTime) { + // Reset to claim's original release time. + setDate(linuxTimestampToDate(releaseTime)); + updatePublishForm({ releaseTimeEdited: undefined }); + } else { + // Reset to "now". + const newDate = new Date(); + setDate(newDate); + updatePublishForm({ releaseTimeEdited: dateToLinuxTimestamp(newDate) }); + } + } else { + // Set to user-defined. + const newDate = value; + setDate(newDate); + updatePublishForm({ releaseTimeEdited: dateToLinuxTimestamp(newDate) }); + } + }; return (
@@ -26,7 +47,7 @@ const PublishReleaseDate = (props: Props) => { className="date-picker-input" calendarClassName="form-field-calendar" onChange={onChange} - value={dateOrToday(releaseTime)} + value={date} maxDate={maxDate} format="y-MM-dd h:mm a" disableClock diff --git a/ui/modal/modalPublishPreview/view.jsx b/ui/modal/modalPublishPreview/view.jsx index f5024c309..0c5c58032 100644 --- a/ui/modal/modalPublishPreview/view.jsx +++ b/ui/modal/modalPublishPreview/view.jsx @@ -29,7 +29,7 @@ type Props = { currency: string, }, language: string, - release_time: ?string, + releaseTimeEdited: ?number, licenseType: string, otherLicenseDescription: ?string, licenseUrl: ?string, @@ -63,7 +63,7 @@ const ModalPublishPreview = (props: Props) => { contentIsFree, fee, language, - release_time, + releaseTimeEdited, licenseType, otherLicenseDescription, licenseUrl, @@ -210,6 +210,10 @@ const ModalPublishPreview = (props: Props) => { ); }; + const releaseTimeStr = (time) => { + return time ? moment(new Date(time * 1000)).format('MMMM Do, YYYY - h:mm a') : ''; + }; + return (
@@ -230,7 +234,7 @@ const ModalPublishPreview = (props: Props) => { {createRow(__('Deposit'), depositValue)} {createRow(__('Price'), priceValue)} {createRow(__('Language'), language)} - {createRow(__('Release Date'), moment(release_time).format('MMMM Do, YYYY - h:mm a'))} + {releaseTimeEdited && createRow(__('Release Date'), releaseTimeStr(releaseTimeEdited))} {createRow(__('License'), licenseValue)} {createRow(__('Tags'), tagsValue)} diff --git a/yarn.lock b/yarn.lock index 3ef3e97a3..d3c14132a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6973,9 +6973,9 @@ lazy-val@^1.0.4: yargs "^13.2.2" zstd-codec "^0.1.1" -lbry-redux@lbryio/lbry-redux#6fc11454eb1b8f9e323c234669880721f12664ee: +lbry-redux@lbryio/lbry-redux#35dd7650fb235109d4a7ab44d1f6dde63dfdf2f7: version "0.0.1" - resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/6fc11454eb1b8f9e323c234669880721f12664ee" + resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/35dd7650fb235109d4a7ab44d1f6dde63dfdf2f7" dependencies: proxy-polyfill "0.1.6" reselect "^3.0.0" -- 2.45.2 From d8e6c4cb36a70915a195368a8ed38367760d8adc Mon Sep 17 00:00:00 2001 From: infinite-persistence Date: Tue, 11 May 2021 15:45:22 +0800 Subject: [PATCH 5/6] Add 'Reset|Now|Default' buttons instead of overloading the date-picker's "X" button. Before this, the "X" button resets to the original (previous) publish date for Edits, and resets to current time for New Claims. This is very confusing, so added explicit text-based buttons -- hopefully this is more intuitive. --- ui/component/publishReleaseDate/index.js | 1 + ui/component/publishReleaseDate/view.jsx | 119 ++++++++++++++++++----- ui/scss/component/_form-field.scss | 9 ++ 3 files changed, 106 insertions(+), 23 deletions(-) diff --git a/ui/component/publishReleaseDate/index.js b/ui/component/publishReleaseDate/index.js index b569fe5d2..67306008a 100644 --- a/ui/component/publishReleaseDate/index.js +++ b/ui/component/publishReleaseDate/index.js @@ -4,6 +4,7 @@ import PublishReleaseDate from './view'; const select = (state) => ({ releaseTime: makeSelectPublishFormValue('releaseTime')(state), + releaseTimeEdited: makeSelectPublishFormValue('releaseTimeEdited')(state), }); const perform = (dispatch) => ({ diff --git a/ui/component/publishReleaseDate/view.jsx b/ui/component/publishReleaseDate/view.jsx index 666481c7a..593d19115 100644 --- a/ui/component/publishReleaseDate/view.jsx +++ b/ui/component/publishReleaseDate/view.jsx @@ -1,5 +1,6 @@ // @flow import React from 'react'; +import Button from 'component/button'; import DateTimePicker from 'react-datetime-picker'; function linuxTimestampToDate(linuxTimestamp: number) { @@ -10,48 +11,120 @@ function dateToLinuxTimestamp(date: Date) { return Number(Math.round(date.getTime() / 1000)); } +const NOW = 'now'; +const DEFAULT = 'default'; +const RESET_TO_ORIGINAL = 'reset-to-original'; + type Props = { releaseTime: ?number, + releaseTimeEdited: ?number, updatePublishForm: ({}) => void, }; const PublishReleaseDate = (props: Props) => { - const { releaseTime, updatePublishForm } = props; + const { releaseTime, releaseTimeEdited, updatePublishForm } = props; const maxDate = new Date(); const [date, setDate] = React.useState(releaseTime ? linuxTimestampToDate(releaseTime) : new Date()); - const onChange = (value) => { - if (!value) { + const isNew = releaseTime === undefined; + const isEdit = !isNew; + + const showEditBtn = isNew && releaseTimeEdited === undefined; + const showDefaultBtn = isNew && releaseTimeEdited !== undefined; + const showDatePicker = isEdit || releaseTimeEdited !== undefined; + + const onDateTimePickerChanged = (value) => { + if (value) { + newDate(value); + } else { + // "!value" should never happen since we now hide the "clear" button, + // but retained the logic here anyway. if (releaseTime) { - // Reset to claim's original release time. - setDate(linuxTimestampToDate(releaseTime)); - updatePublishForm({ releaseTimeEdited: undefined }); + newDate(RESET_TO_ORIGINAL); } else { - // Reset to "now". + newDate(NOW); + } + } + }; + + function newDate(value: string | Date) { + switch (value) { + case NOW: const newDate = new Date(); setDate(newDate); updatePublishForm({ releaseTimeEdited: dateToLinuxTimestamp(newDate) }); - } - } else { - // Set to user-defined. - const newDate = value; - setDate(newDate); - updatePublishForm({ releaseTimeEdited: dateToLinuxTimestamp(newDate) }); + break; + + case DEFAULT: + setDate(undefined); + updatePublishForm({ releaseTimeEdited: undefined }); + break; + + case RESET_TO_ORIGINAL: + if (releaseTime) { + setDate(linuxTimestampToDate(releaseTime)); + updatePublishForm({ releaseTimeEdited: undefined }); + } + break; + + default: + if (value instanceof Date) { + setDate(value); + updatePublishForm({ releaseTimeEdited: dateToLinuxTimestamp(value) }); + } + break; } - }; + } return (
- +
+ {showDatePicker && ( + + )} + {showEditBtn && ( +
); }; diff --git a/ui/scss/component/_form-field.scss b/ui/scss/component/_form-field.scss index ad95a2cb2..a681a2362 100644 --- a/ui/scss/component/_form-field.scss +++ b/ui/scss/component/_form-field.scss @@ -502,6 +502,15 @@ fieldset-section { display: block; } + .controls { + display: flex; + + .date-picker-input, + .button--link { + margin-right: var(--spacing-m); + } + } + .react-datetime-picker__button { svg { stroke: var(--color-text); -- 2.45.2 From 1becd21569f5254dd59863ac21f1c1dcb4b46249 Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Fri, 14 May 2021 17:32:01 -0400 Subject: [PATCH 6/6] bump redux to master --- package.json | 2 +- yarn.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 32ed3407d..ef34ab804 100644 --- a/package.json +++ b/package.json @@ -143,7 +143,7 @@ "imagesloaded": "^4.1.4", "json-loader": "^0.5.4", "lbry-format": "https://github.com/lbryio/lbry-format.git", - "lbry-redux": "lbryio/lbry-redux#35dd7650fb235109d4a7ab44d1f6dde63dfdf2f7", + "lbry-redux": "lbryio/lbry-redux#b2ad71fb745cbc8ead68f89cc37bdf303d68d230", "lbryinc": "lbryio/lbryinc#8f9a58bfc8312a65614fd7327661cdcc502c4e59", "lint-staged": "^7.0.2", "localforage": "^1.7.1", diff --git a/yarn.lock b/yarn.lock index d3c14132a..391576322 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6973,9 +6973,9 @@ lazy-val@^1.0.4: yargs "^13.2.2" zstd-codec "^0.1.1" -lbry-redux@lbryio/lbry-redux#35dd7650fb235109d4a7ab44d1f6dde63dfdf2f7: +lbry-redux@lbryio/lbry-redux#b2ad71fb745cbc8ead68f89cc37bdf303d68d230: version "0.0.1" - resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/35dd7650fb235109d4a7ab44d1f6dde63dfdf2f7" + resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/b2ad71fb745cbc8ead68f89cc37bdf303d68d230" dependencies: proxy-polyfill "0.1.6" reselect "^3.0.0" -- 2.45.2