From 208554089915061d8e8d7d1ae9830be6c4e105f5 Mon Sep 17 00:00:00 2001 From: hackrush Date: Sun, 30 Jul 2017 00:52:17 +0530 Subject: [PATCH 1/3] (quickfix) Now displays two buttons in IncompatibleDaemonModal. The quit and learn more buttons are now displayed separately. --- ui/js/actions/app.js | 8 +++++++- ui/js/component/modalIncompatibleDaemon/index.jsx | 5 +++-- ui/js/component/modalIncompatibleDaemon/view.jsx | 10 ++++++---- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/ui/js/actions/app.js b/ui/js/actions/app.js index 4eae4f1a7..b668b6301 100644 --- a/ui/js/actions/app.js +++ b/ui/js/actions/app.js @@ -297,7 +297,13 @@ export function doClearCache() { }; } -export function doQuitAndLaunchDaemonHelp() { +export function doQuit() { + return function(dispatch, getState) { + remote.app.quit(); + }; +} + +export function doLaunchDaemonHelp() { return function(dispatch, getState) { shell.openExternal("https://lbry.io/faq/incompatible-protocol-version"); remote.app.quit(); diff --git a/ui/js/component/modalIncompatibleDaemon/index.jsx b/ui/js/component/modalIncompatibleDaemon/index.jsx index 27ddecd8d..29670469d 100644 --- a/ui/js/component/modalIncompatibleDaemon/index.jsx +++ b/ui/js/component/modalIncompatibleDaemon/index.jsx @@ -1,13 +1,14 @@ import React from "react"; import { connect } from "react-redux"; import { doQuit, doSkipWrongDaemonNotice } from "actions/app"; -import { doQuitAndLaunchDaemonHelp } from "actions/app"; +import { doLaunchDaemonHelp } from "actions/app"; import ModalIncompatibleDaemon from "./view"; const select = state => ({}); const perform = dispatch => ({ - quitAndLaunchDaemonHelp: () => dispatch(doQuitAndLaunchDaemonHelp()), + quit: () => dispatch(doQuit()), + launchDaemonHelp: () => dispatch(doLaunchDaemonHelp()), }); export default connect(select, perform)(ModalIncompatibleDaemon); diff --git a/ui/js/component/modalIncompatibleDaemon/view.jsx b/ui/js/component/modalIncompatibleDaemon/view.jsx index 851a2ec88..135299850 100644 --- a/ui/js/component/modalIncompatibleDaemon/view.jsx +++ b/ui/js/component/modalIncompatibleDaemon/view.jsx @@ -3,15 +3,17 @@ import { Modal } from "component/modal"; class ModalIncompatibleDaemon extends React.PureComponent { render() { - const { quitAndLaunchDaemonHelp } = this.props; + const { quit, launchDaemonHelp } = this.props; return ( {__( "This browser is running with an incompatible version of the LBRY protocol and your install must be repaired." -- 2.45.2 From d7ceeb15cf3e104893a7463bbef5061eed0fb503 Mon Sep 17 00:00:00 2001 From: 6ea86b96 <6ea86b96@gmail.com> Date: Mon, 17 Jul 2017 13:06:04 +0700 Subject: [PATCH 2/3] Add pagination Some bad pagination CSS --- CHANGELOG.md | 16 +++++++--- ui/js/actions/app.js | 2 +- ui/js/actions/content.js | 15 ++++++--- ui/js/component/router/view.jsx | 34 ++++++++++---------- ui/js/component/wunderbar/index.js | 6 ++-- ui/js/component/wunderbar/view.jsx | 10 ++++-- ui/js/page/channel/index.js | 16 ++++++++-- ui/js/page/channel/view.jsx | 51 ++++++++++++++++++++++++------ ui/js/page/showPage/index.js | 4 +-- ui/js/page/showPage/view.jsx | 9 ++++-- ui/js/reducers/claims.js | 43 ++++++++++++++++++++----- ui/js/reducers/content.js | 11 +++++++ ui/js/selectors/app.js | 12 +++++-- ui/js/selectors/claims.js | 48 +++++++++++++++++++++++++++- ui/js/selectors/content.js | 13 ++++++++ ui/package.json | 3 +- ui/scss/all.scss | 1 + ui/scss/component/_pagination.scss | 18 +++++++++++ ui/yarn.lock | 49 ++++++++++++++++++++++++++-- 19 files changed, 296 insertions(+), 65 deletions(-) create mode 100644 ui/scss/component/_pagination.scss diff --git a/CHANGELOG.md b/CHANGELOG.md index 695df1aa6..10c3f05b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,12 +8,20 @@ Web UI version numbers should always match the corresponding version of LBRY App ## [Unreleased] ### Added - * - * + * Identity verification for new reward participants + * Support rich markup in publishing descriptions and show pages. + * Release past publishing claims (and recover LBC) via the UI + * Added transition to card hovers to smooth animation + * Use randomly colored tiles when image is missing from metadata + * Added a loading message to file actions + * URL is auto suggested in Publish Page + * Added infinite scroll to channel pages ### Changed - * - * + * Publishing revamped. Editing claims is much easier. + * Publish page now use `claim_list` rather than `file_list` + * Daemon updated to [v0.14.2](https://github.com/lbryio/lbry/releases/tag/v0.14.2) + * Made channel claim storage more efficient ### Fixed * diff --git a/ui/js/actions/app.js b/ui/js/actions/app.js index 4eae4f1a7..c8586de86 100644 --- a/ui/js/actions/app.js +++ b/ui/js/actions/app.js @@ -22,7 +22,7 @@ const { download } = remote.require("electron-dl"); const fs = remote.require("fs"); const { lbrySettings: config } = require("../../../app/package.json"); -export function doNavigate(path, params = {}) { +export function doNavigate(path, params = {}, options = {}) { return function(dispatch, getState) { let url = path; if (params) url = `${url}?${toQueryString(params)}`; diff --git a/ui/js/actions/content.js b/ui/js/actions/content.js index 249bb6838..695cbd6ee 100644 --- a/ui/js/actions/content.js +++ b/ui/js/actions/content.js @@ -262,6 +262,7 @@ export function doLoadVideo(uri) { type: types.LOADING_VIDEO_FAILED, data: { uri }, }); + dispatch(doOpenModal("timedOut")); } else { dispatch(doDownloadFile(uri, streamInfo)); @@ -313,22 +314,28 @@ export function doPurchaseUri(uri, purchaseModalName) { }; } -export function doFetchClaimsByChannel(uri, page = 1) { +export function doFetchClaimsByChannel(uri, page) { return function(dispatch, getState) { dispatch({ type: types.FETCH_CHANNEL_CLAIMS_STARTED, - data: { uri }, + data: { uri, page }, }); lbry.claim_list_by_channel({ uri, page }).then(result => { const claimResult = result[uri], - claims = claimResult ? claimResult.claims_in_channel : []; + claims = claimResult ? claimResult.claims_in_channel : [], + totalPages = claimResult + ? claimResult.claims_in_channel_pages + : undefined, + currentPage = claimResult ? claimResult.returned_page : undefined; dispatch({ type: types.FETCH_CHANNEL_CLAIMS_COMPLETED, data: { uri, - claims: claims, + claims, + totalPages, + page: currentPage, }, }); }); diff --git a/ui/js/component/router/view.jsx b/ui/js/component/router/view.jsx index ac3f29921..74ffc836b 100644 --- a/ui/js/component/router/view.jsx +++ b/ui/js/component/router/view.jsx @@ -25,23 +25,23 @@ const Router = props => { const { currentPage, params } = props; return route(currentPage, { - auth: , - channel: , - developer: , - discover: , - downloaded: , - help: , - publish: , - published: , - receive: , - report: , - rewards: , - search: , - send: , - settings: , - show: , - start: , - wallet: , + auth: , + channel: , + developer: , + discover: , + downloaded: , + help: , + publish: , + published: , + receive: , + report: , + rewards: , + search: , + send: , + settings: , + show: , + start: , + wallet: , }); }; diff --git a/ui/js/component/wunderbar/index.js b/ui/js/component/wunderbar/index.js index a6b8860c1..9d23f4d26 100644 --- a/ui/js/component/wunderbar/index.js +++ b/ui/js/component/wunderbar/index.js @@ -12,8 +12,10 @@ const select = state => ({ const perform = dispatch => ({ onSearch: query => dispatch(doNavigate("/search", { query })), - onSubmit: query => - dispatch(doNavigate("/show", { uri: lbryuri.normalize(query) })), + onSubmit: (query, extraParams) => + dispatch( + doNavigate("/show", { uri: lbryuri.normalize(query), ...extraParams }) + ), }); export default connect(select, perform)(Wunderbar); diff --git a/ui/js/component/wunderbar/view.jsx b/ui/js/component/wunderbar/view.jsx index 673b015a5..04ba1a030 100644 --- a/ui/js/component/wunderbar/view.jsx +++ b/ui/js/component/wunderbar/view.jsx @@ -1,6 +1,7 @@ import React from "react"; import lbryuri from "lbryuri.js"; import { Icon } from "component/common.js"; +import { parseQueryParams } from "util/query_params"; class WunderBar extends React.PureComponent { static TYPING_TIMEOUT = 800; @@ -120,12 +121,15 @@ class WunderBar extends React.PureComponent { onKeyPress(event) { if (event.charCode == 13 && this._input.value) { let uri = null, - method = "onSubmit"; + method = "onSubmit", + extraParams = {}; this._resetOnNextBlur = false; clearTimeout(this._userTypingTimer); - const value = this._input.value.trim(); + const parts = this._input.value.trim().split("?"); + const value = parts.shift(); + if (parts.length > 0) extraParams = parseQueryParams(parts.join("")); try { uri = lbryuri.normalize(value); @@ -136,7 +140,7 @@ class WunderBar extends React.PureComponent { method = "onSearch"; } - this.props[method](uri); + this.props[method](uri, extraParams); this._input.blur(); } } diff --git a/ui/js/page/channel/index.js b/ui/js/page/channel/index.js index 5e2be42ea..bce739e1e 100644 --- a/ui/js/page/channel/index.js +++ b/ui/js/page/channel/index.js @@ -3,24 +3,34 @@ import { connect } from "react-redux"; import { doFetchClaimsByChannel } from "actions/content"; import { makeSelectClaimForUri, - makeSelectClaimsInChannelForUri, + makeSelectClaimsInChannelForCurrentPage, + makeSelectFetchingChannelClaims, } from "selectors/claims"; +import { selectCurrentParams } from "selectors/app"; +import { doNavigate } from "actions/app"; +import { makeSelectTotalPagesForChannel } from "selectors/content"; import ChannelPage from "./view"; const makeSelect = () => { const selectClaim = makeSelectClaimForUri(), - selectClaimsInChannel = makeSelectClaimsInChannelForUri(); + selectClaimsInChannel = makeSelectClaimsInChannelForCurrentPage(), + selectFetchingChannelClaims = makeSelectFetchingChannelClaims(), + selectTotalPagesForChannel = makeSelectTotalPagesForChannel(); const select = (state, props) => ({ claim: selectClaim(state, props), claimsInChannel: selectClaimsInChannel(state, props), + fetching: selectFetchingChannelClaims(state, props), + totalPages: selectTotalPagesForChannel(state, props), + params: selectCurrentParams(state), }); return select; }; const perform = dispatch => ({ - fetchClaims: uri => dispatch(doFetchClaimsByChannel(uri)), + fetchClaims: (uri, page) => dispatch(doFetchClaimsByChannel(uri, page)), + navigate: (path, params) => dispatch(doNavigate(path, params)), }); export default connect(makeSelect, perform)(ChannelPage); diff --git a/ui/js/page/channel/view.jsx b/ui/js/page/channel/view.jsx index 377069330..172e431f9 100644 --- a/ui/js/page/channel/view.jsx +++ b/ui/js/page/channel/view.jsx @@ -2,24 +2,41 @@ import React from "react"; import lbryuri from "lbryuri"; import { BusyMessage } from "component/common"; import FileTile from "component/fileTile"; +import Link from "component/link"; +import ReactPaginate from "react-paginate"; class ChannelPage extends React.PureComponent { componentDidMount() { - this.fetchClaims(this.props); + const { uri, params, fetchClaims } = this.props; + + fetchClaims(uri, params.page || 1); } componentWillReceiveProps(nextProps) { - this.fetchClaims(nextProps); + const { params, fetching, fetchClaims } = this.props; + const nextParams = nextProps.params; + + if (fetching !== nextParams.page && params.page !== nextParams.page) + fetchClaims(nextProps.uri, nextParams.page); } - fetchClaims(props) { - if (props.claimsInChannel === undefined) { - props.fetchClaims(props.uri); - } + changePage(pageNumber) { + const { params, currentPage } = this.props; + const newParams = Object.assign({}, params, { page: pageNumber }); + + this.props.navigate("/show", newParams); } render() { - const { claimsInChannel, claim, uri } = this.props; + const { + fetching, + claimsInChannel, + claim, + uri, + params, + totalPages, + } = this.props; + const { page } = params; let contentList; if (claimsInChannel === undefined) { @@ -29,14 +46,17 @@ class ChannelPage extends React.PureComponent { ? claimsInChannel.map(claim => ) : {__("No content found.")}; } return ( -
+

{uri}

@@ -51,7 +71,18 @@ class ChannelPage extends React.PureComponent {

{__("Published Content")}

{contentList} -
+
+ {(!fetching || (claimsInChannel && claimsInChannel.length)) && + totalPages > 1 && + this.changePage(e.selected + 1)} + initialPage={parseInt(page - 1)} + containerClassName="pagination" + />} +
); } } diff --git a/ui/js/page/showPage/index.js b/ui/js/page/showPage/index.js index cd9677169..6306e5e33 100644 --- a/ui/js/page/showPage/index.js +++ b/ui/js/page/showPage/index.js @@ -10,8 +10,8 @@ const makeSelect = () => { selectIsResolving = makeSelectIsResolvingForUri(); const select = (state, props) => ({ - claim: selectClaim(state, props), - isResolvingUri: selectIsResolving(state, props), + claim: selectClaim(state, props.params), + isResolvingUri: selectIsResolving(state, props.params), }); return select; diff --git a/ui/js/page/showPage/view.jsx b/ui/js/page/showPage/view.jsx index 687cb5498..67bbf6178 100644 --- a/ui/js/page/showPage/view.jsx +++ b/ui/js/page/showPage/view.jsx @@ -6,13 +6,15 @@ import FilePage from "page/filePage"; class ShowPage extends React.PureComponent { componentWillMount() { - const { isResolvingUri, resolveUri, uri } = this.props; + const { isResolvingUri, resolveUri, params } = this.props; + const { uri } = params; if (!isResolvingUri) resolveUri(uri); } componentWillReceiveProps(nextProps) { - const { isResolvingUri, resolveUri, claim, uri } = nextProps; + const { isResolvingUri, resolveUri, claim, params } = nextProps; + const { uri } = params; if (!isResolvingUri && claim === undefined && uri) { resolveUri(uri); @@ -20,7 +22,8 @@ class ShowPage extends React.PureComponent { } render() { - const { claim, uri, isResolvingUri } = this.props; + const { claim, params, isResolvingUri } = this.props; + const { uri } = params; let innerContent = ""; diff --git a/ui/js/reducers/claims.js b/ui/js/reducers/claims.js index 9e072f1ce..c70fd45e0 100644 --- a/ui/js/reducers/claims.js +++ b/ui/js/reducers/claims.js @@ -101,17 +101,44 @@ reducers[types.FETCH_CHANNEL_LIST_MINE_COMPLETED] = function(state, action) { }); }; -reducers[types.FETCH_CHANNEL_CLAIMS_COMPLETED] = function(state, action) { - const { uri, claims } = action.data; +reducers[types.FETCH_CHANNEL_CLAIMS_STARTED] = function(state, action) { + const { uri, page } = action.data; + const fetchingChannelClaims = Object.assign({}, state.fetchingChannelClaims); - const newClaims = Object.assign({}, state.claimsByChannel); - - if (claims !== undefined) { - newClaims[uri] = claims; - } + fetchingChannelClaims[uri] = page; return Object.assign({}, state, { - claimsByChannel: newClaims, + fetchingChannelClaims, + }); +}; + +reducers[types.FETCH_CHANNEL_CLAIMS_COMPLETED] = function(state, action) { + const { uri, claims, page } = action.data; + + const claimsByChannel = Object.assign({}, state.claimsByChannel); + const byChannel = Object.assign({}, claimsByChannel[uri]); + const allClaimIds = new Set(byChannel["all"]); + const currentPageClaimIds = []; + const byId = Object.assign({}, state.byId); + const fetchingChannelClaims = Object.assign({}, state.fetchingChannelClaims); + + if (claims !== undefined) { + claims.forEach(claim => { + allClaimIds.add(claim.claim_id); + currentPageClaimIds.push(claim.claim_id); + byId[claim.claim_id] = claim; + }); + } + + byChannel["all"] = allClaimIds; + byChannel[page] = currentPageClaimIds; + claimsByChannel[uri] = byChannel; + delete fetchingChannelClaims[uri]; + + return Object.assign({}, state, { + claimsByChannel, + byId, + fetchingChannelClaims, }); }; diff --git a/ui/js/reducers/content.js b/ui/js/reducers/content.js index f346e2d27..0e1d71fed 100644 --- a/ui/js/reducers/content.js +++ b/ui/js/reducers/content.js @@ -47,6 +47,17 @@ reducers[types.RESOLVE_URI_CANCELED] = reducers[ }); }; +reducers[types.FETCH_CHANNEL_CLAIMS_COMPLETED] = function(state, action) { + const channelPages = Object.assign({}, state.channelPages); + const { uri, totalPages } = action.data; + + channelPages[uri] = totalPages; + + return Object.assign({}, state, { + channelPages, + }); +}; + export default function reducer(state = defaultState, action) { const handler = reducers[action.type]; if (handler) return handler(state, action); diff --git a/ui/js/selectors/app.js b/ui/js/selectors/app.js index 3951a8216..a67dc9f37 100644 --- a/ui/js/selectors/app.js +++ b/ui/js/selectors/app.js @@ -1,5 +1,5 @@ import { createSelector } from "reselect"; -import { parseQueryParams } from "util/query_params"; +import { parseQueryParams, toQueryString } from "util/query_params"; import lbry from "lbry"; import lbryuri from "lbryuri"; @@ -55,8 +55,14 @@ export const selectPageTitle = createSelector( return params.query ? __("Search results for %s", params.query) : __("Search"); - case "show": - return lbryuri.normalize(params.uri); + case "show": { + const parts = [lbryuri.normalize(params.uri)]; + // If the params has any keys other than "uri" + if (Object.keys(params).length > 1) { + parts.push(toQueryString(Object.assign({}, params, { uri: null }))); + } + return parts.join("?"); + } case "downloaded": return __("Downloads & Purchases"); case "published": diff --git a/ui/js/selectors/claims.js b/ui/js/selectors/claims.js index 3c10ec931..2c4b4b511 100644 --- a/ui/js/selectors/claims.js +++ b/ui/js/selectors/claims.js @@ -1,4 +1,5 @@ import { createSelector } from "reselect"; +import { selectCurrentParams } from "selectors/app"; import lbryuri from "lbryuri"; const _selectState = state => state.claims || {}; @@ -60,14 +61,59 @@ export const makeSelectClaimForUriIsMine = () => { return createSelector(selectClaimForUriIsMine, isMine => isMine); }; +export const selectAllFetchingChannelClaims = createSelector( + _selectState, + state => state.fetchingChannelClaims || {} +); + +const selectFetchingChannelClaims = (state, props) => { + const allFetchingChannelClaims = selectAllFetchingChannelClaims(state); + + return allFetchingChannelClaims[props.uri]; +}; + +export const makeSelectFetchingChannelClaims = (state, props) => { + return createSelector(selectFetchingChannelClaims, fetching => fetching); +}; + export const selectClaimsInChannelForUri = (state, props) => { - return selectAllClaimsByChannel(state)[props.uri]; + const byId = selectClaimsById(state); + const byChannel = selectAllClaimsByChannel(state)[props.uri] || {}; + const claimIds = byChannel["all"]; + + if (!claimIds) return claimIds; + + const claims = []; + + claimIds.forEach(claimId => claims.push(byId[claimId])); + + return claims; }; export const makeSelectClaimsInChannelForUri = () => { return createSelector(selectClaimsInChannelForUri, claims => claims); }; +export const selectClaimsInChannelForCurrentPage = (state, props) => { + const byId = selectClaimsById(state); + const byChannel = selectAllClaimsByChannel(state)[props.uri] || {}; + const params = selectCurrentParams(state); + const page = params && params.page ? params.page : 1; + const claimIds = byChannel[page]; + + if (!claimIds) return claimIds; + + const claims = []; + + claimIds.forEach(claimId => claims.push(byId[claimId])); + + return claims; +}; + +export const makeSelectClaimsInChannelForCurrentPage = () => { + return createSelector(selectClaimsInChannelForCurrentPage, claims => claims); +}; + const selectMetadataForUri = (state, props) => { const claim = selectClaimForUri(state, props); const metadata = diff --git a/ui/js/selectors/content.js b/ui/js/selectors/content.js index 75162a454..663aab145 100644 --- a/ui/js/selectors/content.js +++ b/ui/js/selectors/content.js @@ -24,3 +24,16 @@ const selectResolvingUri = (state, props) => { export const makeSelectIsResolvingForUri = () => { return createSelector(selectResolvingUri, resolving => resolving); }; + +export const selectChannelPages = createSelector( + _selectState, + state => state.channelPages || {} +); + +const selectTotalPagesForChannel = (state, props) => { + return selectChannelPages(state)[props.uri]; +}; + +export const makeSelectTotalPagesForChannel = () => { + return createSelector(selectTotalPagesForChannel, totalPages => totalPages); +}; diff --git a/ui/package.json b/ui/package.json index fd9137ba5..5d447d6a4 100644 --- a/ui/package.json +++ b/ui/package.json @@ -31,6 +31,7 @@ "react-dom": "^15.4.0", "react-markdown": "^2.5.0", "react-modal": "^1.5.2", + "react-paginate": "^4.4.3", "react-redux": "^5.0.3", "react-simplemde-editor": "^3.6.11", "redux": "^3.6.0", @@ -54,8 +55,8 @@ "babel-preset-es2015": "^6.24.1", "babel-preset-react": "^6.24.1", "babel-preset-stage-2": "^6.18.0", - "electron-rebuild": "^1.5.11", "css-loader": "^0.28.4", + "electron-rebuild": "^1.5.11", "eslint": "^3.10.2", "eslint-config-airbnb": "^13.0.0", "eslint-loader": "^1.6.1", diff --git a/ui/scss/all.scss b/ui/scss/all.scss index 61612d7df..d899566ab 100644 --- a/ui/scss/all.scss +++ b/ui/scss/all.scss @@ -17,6 +17,7 @@ @import "component/_modal.scss"; @import "component/_snack-bar.scss"; @import "component/_video.scss"; +@import "component/_pagination.scss"; @import "page/_developer.scss"; @import "page/_reward.scss"; @import "page/_show.scss"; diff --git a/ui/scss/component/_pagination.scss b/ui/scss/component/_pagination.scss new file mode 100644 index 000000000..b16076f76 --- /dev/null +++ b/ui/scss/component/_pagination.scss @@ -0,0 +1,18 @@ +ul.pagination { + display: inline-block; + padding: 0; + margin: 0; +} + +ul.pagination li { + display: inline; + float: left; + padding: 8px 16px; +} + +ul.pagination li:not(.selected) { + background: white; + a { + cursor: hand; + } +} diff --git a/ui/yarn.lock b/ui/yarn.lock index cb2ca85fb..5d5848976 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -1204,6 +1204,10 @@ clap@^1.0.9: dependencies: chalk "^1.1.3" +classnames@^2.2.5: + version "2.2.5" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d" + cli-cursor@^1.0.1, cli-cursor@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" @@ -2329,6 +2333,14 @@ faye-websocket@~0.11.0: dependencies: websocket-driver ">=0.5.1" +fbjs@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.2.1.tgz#622061630a43e11f845017b9044aaa648ed3f731" + dependencies: + core-js "^1.0.0" + promise "^7.0.3" + whatwg-fetch "^0.9.0" + fbjs@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.6.1.tgz#9636b7705f5ba9684d44b72f78321254afc860f7" @@ -2339,7 +2351,7 @@ fbjs@^0.6.1: ua-parser-js "^0.7.9" whatwg-fetch "^0.9.0" -fbjs@^0.8.9: +fbjs@^0.8.4, fbjs@^0.8.9: version "0.8.12" resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.12.tgz#10b5d92f76d45575fd63a217d4ea02bea2f8ed04" dependencies: @@ -4771,10 +4783,26 @@ rc@^1.1.7: minimist "^1.2.0" strip-json-comments "~2.0.1" +react-addons-create-fragment@^0.14.7: + version "0.14.8" + resolved "https://registry.yarnpkg.com/react-addons-create-fragment/-/react-addons-create-fragment-0.14.8.tgz#e83240d1cba49249690fcc6f148710baa11d2b7a" + +react-addons-create-fragment@^15.0.0: + version "15.6.0" + resolved "https://registry.yarnpkg.com/react-addons-create-fragment/-/react-addons-create-fragment-15.6.0.tgz#af91a22b1fb095dd01f1afba43bfd0ef589d8b20" + dependencies: + fbjs "^0.8.4" + loose-envify "^1.3.1" + object-assign "^4.1.0" + react-dom-factories@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/react-dom-factories/-/react-dom-factories-1.0.0.tgz#f43c05e5051b304f33251618d5bc859b29e46b6d" +react-dom@^0.14.7: + version "0.14.9" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-0.14.9.tgz#05064a3dcf0fb1880a3b2bfc9d58c55d8d9f6293" + react-dom@^15.4.0: version "15.6.1" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.6.1.tgz#2cb0ed4191038e53c209eb3a79a23e2a4cf99470" @@ -4804,6 +4832,15 @@ react-modal@^1.5.2: prop-types "^15.5.7" react-dom-factories "^1.0.0" +react-paginate@^4.4.3: + version "4.4.3" + resolved "https://registry.yarnpkg.com/react-paginate/-/react-paginate-4.4.3.tgz#11817ece628fa59c54a2df7968c854ed64b99077" + dependencies: + classnames "^2.2.5" + prop-types "^15.5.7" + react "^15.0.0" + react-addons-create-fragment "^15.0.0" + react-redux@^5.0.3: version "5.0.5" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.5.tgz#f8e8c7b239422576e52d6b7db06439469be9846a" @@ -4823,14 +4860,20 @@ react-simplemde-editor@^3.6.11: react "^0.14.2" simplemde "^1.11.2" -react@^0.14.2: +react-tap-event-plugin@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/react-tap-event-plugin/-/react-tap-event-plugin-0.2.2.tgz#4f6f257851654f6c2b1c213a1d3ff21b353ae4e1" + dependencies: + fbjs "^0.2.1" + +react@^0.14.2, react@^0.14.7: version "0.14.9" resolved "https://registry.yarnpkg.com/react/-/react-0.14.9.tgz#9110a6497c49d44ba1c0edd317aec29c2e0d91d1" dependencies: envify "^3.0.0" fbjs "^0.6.1" -react@^15.4.0: +react@^15.0.0, react@^15.4.0: version "15.6.1" resolved "https://registry.yarnpkg.com/react/-/react-15.6.1.tgz#baa8434ec6780bde997cdc380b79cd33b96393df" dependencies: -- 2.45.2 From 16c2eb94791043e406fa1863d79eff74c1d2fd5c Mon Sep 17 00:00:00 2001 From: Jeremy Kauffman Date: Sat, 29 Jul 2017 15:34:22 -0400 Subject: [PATCH 3/3] pagination styles --- ui/js/page/channel/view.jsx | 6 +++++ ui/scss/component/_pagination.scss | 40 ++++++++++++++++++++---------- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/ui/js/page/channel/view.jsx b/ui/js/page/channel/view.jsx index 172e431f9..d694c3ba8 100644 --- a/ui/js/page/channel/view.jsx +++ b/ui/js/page/channel/view.jsx @@ -77,6 +77,12 @@ class ChannelPage extends React.PureComponent { this.changePage(e.selected + 1)} initialPage={parseInt(page - 1)} diff --git a/ui/scss/component/_pagination.scss b/ui/scss/component/_pagination.scss index b16076f76..940dd11bd 100644 --- a/ui/scss/component/_pagination.scss +++ b/ui/scss/component/_pagination.scss @@ -1,18 +1,32 @@ -ul.pagination { - display: inline-block; +@import "../global"; + +.pagination { + display: block; padding: 0; - margin: 0; + margin: 0 auto; + text-align: center; } -ul.pagination li { - display: inline; - float: left; - padding: 8px 16px; -} - -ul.pagination li:not(.selected) { - background: white; - a { - cursor: hand; +.pagination__item { + display: inline-block; + line-height: $spacing-vertical * 1.5; + height: $spacing-vertical * 1.5; + border-radius: 2px; + &:not(.pagination__item--selected):hover { + background: rgba(0, 0, 0, 0.2); + > a { cursor: hand } + } + > a { + display: inline-block; + padding: 0 $spacing-vertical * 2 / 3; } } + +.pagination__item--previous, .pagination__item--next { + font-size: 1.2em; +} + +.pagination__item--selected { + color: white; + background: $color-primary; +} -- 2.45.2