diff --git a/packages/@beaverbuilder/app-core/package.json b/packages/@beaverbuilder/app-core/package.json index 1b01ee13f..c5f799168 100644 --- a/packages/@beaverbuilder/app-core/package.json +++ b/packages/@beaverbuilder/app-core/package.json @@ -1,6 +1,6 @@ { "name": "@beaverbuilder/app-core", - "version": "0.2.2", + "version": "0.2.3", "description": "Utilities for managing an app registry.", "author": "The Beaver Builder Team", "license": "GPL-2.0+", diff --git a/packages/@beaverbuilder/app-core/src/app/content.js b/packages/@beaverbuilder/app-core/src/app/content.js index 5b6596b4e..618a09340 100644 --- a/packages/@beaverbuilder/app-core/src/app/content.js +++ b/packages/@beaverbuilder/app-core/src/app/content.js @@ -51,7 +51,7 @@ const Content = ( { } const CurrentApp = ( { - loading: LoadingScreen, + loading: defaultLoadingScreen, error: ErrorScreen = DefaultErrorScreen, apps, } ) => { @@ -72,7 +72,7 @@ const CurrentApp = ( { return null } - const { label = '', root } = apps[ handle ] + const { label = '', root, loading: appLoadingScreen } = apps[ handle ] const isAppRoot = 2 >= location.pathname.split( '/' ).length const context = { @@ -83,6 +83,8 @@ const CurrentApp = ( { isAppRoot, } + const LoadingScreen = appLoadingScreen ? appLoadingScreen : defaultLoadingScreen + return ( diff --git a/src/apps/fl-home/ui/shell/style.scss b/src/apps/fl-home/ui/shell/style.scss index c9f2dccea..a1f63a30e 100644 --- a/src/apps/fl-home/ui/shell/style.scss +++ b/src/apps/fl-home/ui/shell/style.scss @@ -80,6 +80,18 @@ .fluid-page.fl-asst-home-shell { .fl-asst-home-shell-sidebar { background: hsl( var(--fluid-hue), 10%, 12% ); + + .fl-asst-home-shell-sidebar-section { + ul { + li { + a, button { + &.is-selected { + background: var(--fluid-opaque-3); + } + } + } + } + } } } } diff --git a/src/apps/fl-media/app.js b/src/apps/fl-media/app.js index 07f493d16..9af6a858a 100644 --- a/src/apps/fl-media/app.js +++ b/src/apps/fl-media/app.js @@ -1,22 +1,34 @@ import React from 'react' -import { __ } from '@wordpress/i18n' -import { App, Page, List, Filter, Button, Icon, Media } from 'assistant/ui' -import { useAppState, getAppActions } from 'assistant/data' -import { defaultState } from './data' -import { UploadCard, FileList } from './ui' -import AppIcon from './icon' -import './style.scss' +import { AnimateSharedLayout } from 'framer-motion' +import { App, Page } from 'assistant/ui' +import { Shell, MediaList } from './ui' +import { MediaAppProvider } from './data' -export default props => ( - -) +export default props => { + return ( + + + + + + ) +} + +const Main = () => { + return ( + + + + ) +} +/* const Main = ( { baseURL } ) => { const { listStyle, query, showUploader } = useAppState( 'fl-media' ) const { setListStyle, setQuery, setShowUploader } = getAppActions( 'fl-media' ) @@ -153,3 +165,4 @@ const Main = ( { baseURL } ) => { ) } +*/ diff --git a/src/apps/fl-media/config/index.js b/src/apps/fl-media/config/index.js new file mode 100644 index 000000000..4e6ecb24e --- /dev/null +++ b/src/apps/fl-media/config/index.js @@ -0,0 +1,13 @@ +export const defaultState = { + listStyle: 'grid', + query: { + post_mime_type: 'all', + order: 'DESC', + orderby: 'date', + label: '0', + }, + showUploader: true, + lastViewed: null, +} + +export const cache = [ 'listStyle', 'query', 'showUploader' ] diff --git a/src/apps/fl-media/data/index.js b/src/apps/fl-media/data/index.js index c79d40d7e..c01fa9d6b 100644 --- a/src/apps/fl-media/data/index.js +++ b/src/apps/fl-media/data/index.js @@ -1,12 +1,74 @@ -export const defaultState = { - listStyle: 'grid', - query: { - post_mime_type: 'all', - order: 'DESC', - orderby: 'date', - label: '0', - }, - showUploader: true, +import React, { useContext, createContext } from 'react' +import { __ } from '@wordpress/i18n' +import { Icon, Media } from 'assistant/ui' +import { useAppState, getAppActions } from 'assistant/data' +import { useAttachments } from 'assistant/utils/wordpress' + +export const MediaAppContext = createContext( {} ) + +export const useMediaApp = () => useContext( MediaAppContext ) + +export const MediaAppProvider = ( { children } ) => { + const { query, lastViewed, showUploader } = useAppState( 'fl-media' ) + const { setQuery, setLastViewed, setShowUploader } = getAppActions( 'fl-media' ) + const attachments = useAttachments( query ) + const { files, uploadFiles: _uploadFiles, current } = Media.useMediaUploads() + + const uploadFiles = files => { + setQuery( { ...query } ) + _uploadFiles( files, () => { + console.log( 'upload complete' ) + attachments.reloadItems() + } ) + } + + const context = { + + // All the attachment REST info + ...attachments, + + // Current query + query, + setQuery, + + // Info about file uploads and the uploader UI + uploads: files, + uploadFiles, + currentUpload: current, + showUploader, + setShowUploader, + + // ID of the last viewed attachment detail page + lastViewed, + setLastViewed, + } + + return ( + + {children} + + ) } -export const cache = [ 'listStyle', 'query', 'showUploader' ] +export const attachmentTypes = { + all: { + label: __( 'Everything' ), + icon: Icon.Placeholder + }, + image: { + label: __( 'Photos' ), + icon: Icon.Placeholder + }, + video: { + label: __( 'Videos' ), + icon: Icon.Video + }, + audio: { + label: __( 'Audio' ), + icon: Icon.Audio + }, + document: { + label: __( 'Documents' ), + icon: Icon.Document + }, +} diff --git a/src/apps/fl-media/index.js b/src/apps/fl-media/index.js index e636a6ada..cf36fa0e9 100644 --- a/src/apps/fl-media/index.js +++ b/src/apps/fl-media/index.js @@ -4,7 +4,8 @@ import { __ } from '@wordpress/i18n' import { addQueryArgs } from 'assistant/utils/url' import { Page } from 'assistant/ui' import Icon from './icon' -import { defaultState, cache } from './data' +import LoadingScreen from './loading-screen' +import { defaultState, cache } from './config' const App = lazy( () => import( /* webpackChunkName: "app-media" */ './app' @@ -14,6 +15,7 @@ registerApp( 'fl-media', { label: __( 'Media' ), root: App, icon: Icon, + loading: LoadingScreen, state: { ...defaultState }, search: { label: __( 'Media' ), diff --git a/src/apps/fl-media/loading-screen/index.js b/src/apps/fl-media/loading-screen/index.js new file mode 100644 index 000000000..9a44a2387 --- /dev/null +++ b/src/apps/fl-media/loading-screen/index.js @@ -0,0 +1,13 @@ +import React from 'react' +import { Layout } from 'assistant/ui' +import './style.scss' + +const LoadingScreen = () => { + return ( +
+ +
+ ) +} + +export default LoadingScreen diff --git a/src/apps/fl-media/loading-screen/style.scss b/src/apps/fl-media/loading-screen/style.scss new file mode 100644 index 000000000..2baf0cfec --- /dev/null +++ b/src/apps/fl-media/loading-screen/style.scss @@ -0,0 +1,5 @@ +.fl-asst-media-loading-screen { + flex: 1 1 auto; + display: grid; + grid-template-columns: 220px 1fr; +} diff --git a/src/apps/fl-media/ui/file-list/index.js b/src/apps/fl-media/ui/file-list/index.js deleted file mode 100644 index 6980e1505..000000000 --- a/src/apps/fl-media/ui/file-list/index.js +++ /dev/null @@ -1,39 +0,0 @@ -import React from 'react' -import { Icon } from 'assistant/ui' -import './style.scss' - -const FileList = ( { files = [], current } ) => { - if ( current > files.length ) { - return null - } - return ( - <> -
    - { files.map( ( file, i ) => { - - // Remove items that have already been uploaded - if ( i + 1 < current ) { - return null - } - - return ( -
  • - - { file.name } - -
  • - ) - } ) } -
- - ) -} - -export default FileList diff --git a/src/apps/fl-media/ui/file-list/style.scss b/src/apps/fl-media/ui/file-list/style.scss deleted file mode 100644 index b0c5ad292..000000000 --- a/src/apps/fl-media/ui/file-list/style.scss +++ /dev/null @@ -1,22 +0,0 @@ -.fl-asst { - .fl-asst-file-list { - background: var(--fluid-transparent-12); - padding: var(--fluid-lg-space); - border-radius: var(--fluid-radius); - margin: var(--fluid-med-space) var(--fluid-med-space) 0; - - li { - min-height: 36px; - display: flex; - align-items: center; - padding: 5px 0; - font-size: 12px; - } - } -} -.fluid-color-scheme-dark { - .fl-asst-file-list { - background: var(--fluid-transparent-1); - color: var(--fluid-color); - } -} diff --git a/src/apps/fl-media/ui/index.js b/src/apps/fl-media/ui/index.js index bc9811ec5..f27ecabf6 100644 --- a/src/apps/fl-media/ui/index.js +++ b/src/apps/fl-media/ui/index.js @@ -1,4 +1,6 @@ import UploadCard from './upload-card' -import FileList from './file-list' +import MediaList from './list' +import Shell from './shell' +import './style.scss' -export { UploadCard, FileList } +export { UploadCard, Shell, MediaList } diff --git a/src/apps/fl-media/ui/list/file-list/index.js b/src/apps/fl-media/ui/list/file-list/index.js new file mode 100644 index 000000000..742dba5a2 --- /dev/null +++ b/src/apps/fl-media/ui/list/file-list/index.js @@ -0,0 +1,25 @@ +import React from 'react' +import { UploadingItem } from '../items' + +const FileList = ( { files = [], current } ) => { + if ( current > files.length ) { + return null + } + return files.map( ( file, i ) => { + + // Remove items that have already been uploaded + if ( i + 1 < current ) { + return null + } + + const src = URL.createObjectURL( file ) + + return ( +
  • + +
  • + ) + } ) +} + +export default FileList diff --git a/src/apps/fl-media/ui/list/index.js b/src/apps/fl-media/ui/list/index.js new file mode 100644 index 000000000..f3b0ab254 --- /dev/null +++ b/src/apps/fl-media/ui/list/index.js @@ -0,0 +1,108 @@ +import React, { useLayoutEffect } from 'react' +import { __, sprintf } from '@wordpress/i18n' +import { Text } from 'assistant/ui' +import { useMediaApp } from '../../data' +import { AttachmentItem, PlaceholderItem } from './items' +import UploadCard from '../upload-card' +import FileList from './file-list' +import './style.scss' + +const hasReachedBounds = e => { + const { scrollTop, clientHeight, scrollHeight } = e.target + const bottom = scrollTop + clientHeight + return bottom + 150 >= scrollHeight +} + +const MediaList = () => { + const { + items, + isFetching, + loadItems, + hasMore, + lastViewed, + setLastViewed, + uploads, + uploadFiles, + currentUpload, + showUploader, + setShowUploader, + } = useMediaApp() + const hasItems = 0 < items.length + + const placeholders = new Array( 18 ).fill( 18 ) + const displayPlaceholders = isFetching && ! hasItems + + const onScroll = e => { + if ( hasMore && hasReachedBounds( e ) && ! isFetching ) { + loadItems( items.length ) + } + } + + useLayoutEffect( () => { + + if ( null === lastViewed ) { + return + } + const el = document.getElementById( `attachment-${lastViewed}` ) + if ( el ) { + el.scrollIntoView( { block: 'center' } ) + setLastViewed( null ) + } + }, [] ) + + return ( +
    + +
      + + { showUploader && ( +
    • + setShowUploader( false ) } + /> +
    • + ) } + + { 0 < uploads.length && ( + + ) } + + { displayPlaceholders && placeholders.map( ( _, i ) => ( +
    • + +
    • + ) ) } + + { items.map( item => { + return ( +
    • + setLastViewed( item.id ) } + { ...item } + /> +
    • + ) + } ) } + +
    + +
    + ) +} + +const Endcap = ( { isFetching = false, totalItems = 0 } ) => { + return ( +
  • + { isFetching && { __( 'Loading...', 'fl-assistant' ) } } + { ! isFetching && ( + { sprintf( '%s Items', totalItems ) } + ) } +
  • + ) +} + +export default MediaList diff --git a/src/apps/fl-media/ui/list/items/art/index.js b/src/apps/fl-media/ui/list/items/art/index.js new file mode 100644 index 000000000..d3a0bff8d --- /dev/null +++ b/src/apps/fl-media/ui/list/items/art/index.js @@ -0,0 +1,25 @@ +import React from 'react' + +const Image = () => {} + +Image.Video = () => ( + + + + +) + +Image.Doc = () => ( + + + +) + +Image.Audio = () => ( + + + + +) + +export default Image diff --git a/src/apps/fl-media/ui/list/items/index.js b/src/apps/fl-media/ui/list/items/index.js new file mode 100644 index 000000000..289b09471 --- /dev/null +++ b/src/apps/fl-media/ui/list/items/index.js @@ -0,0 +1,75 @@ +import React from 'react' +import { Link } from 'react-router-dom' +import { motion } from 'framer-motion' +import { Layout } from 'assistant/ui' +import { getSrcSet } from 'assistant/utils/image' +import Image from './art' + +const filterSizes = sizes => { + const smallSizes = {} + const allow = [ 'thumbnail', 'medium' ] + for ( let key in sizes ) { + if ( allow.includes( key ) ) { + smallSizes[key] = sizes[key] + } + } + return smallSizes +} + +export const AttachmentItem = props => { + const { + thumbnail, + type, + subtype, + alt, + title, + sizes, + id, + isTrashed, + onClick = () => {} + } = props + const isDocument = ( 'application' === type || ( 'pdf' === subtype && ! thumbnail ) ) + + // Filter down to just the smaller sizes for srcset + const smallSizes = filterSizes( sizes ) + const to = isTrashed ? '' : { + pathname: `/fl-media/attachment/${id}`, + state: { item: props } + } + + return ( + + + { ( 'image' === type || 'pdf' === subtype ) && thumbnail && ( + { + ) } + { 'video' === type && } + { 'audio' === type && } + { isDocument && } + + + ) +} + +export const PlaceholderItem = () => { + return ( + + ) +} + +export const UploadingItem = ( { ...rest } ) => { + return ( + + +
    + +
    +
    + ) +} diff --git a/src/apps/fl-media/ui/list/style.scss b/src/apps/fl-media/ui/list/style.scss new file mode 100644 index 000000000..92e72ddd8 --- /dev/null +++ b/src/apps/fl-media/ui/list/style.scss @@ -0,0 +1,88 @@ +.fl-asst-media-app-list-scroller { + flex: 1 1 auto; + max-height: 100%; + min-height: 0; + overflow: auto; +} +ul.fl-asst-media-app-list { + display: grid; + grid-gap: var(--fluid-lg-space); + grid-template-columns: repeat( auto-fill, minmax( 135px, 1fr ) ); + padding: var(--fluid-lg-space); + padding-top: 0; + margin: 0; + + li { + position: relative; + background: var(--fluid-box-background); + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + border-radius: var(--fluid-radius); + + &:before { + content: ""; + padding-bottom: 100%; + display: block; + } + + a, button { + display: block; + } + + img { + width: 100%; + height: 100%; + object-fit: contain; + border-radius: 5px; + } + + .fl-asst-media-item-box { + position: absolute; + top:0; + left:0; + width: 100%; + height: 100%; + + display: flex; + justify-content: center; + align-items: center; + + z-index: 2; + filter: brightness( 98% ); + } + } + + .fl-asst-media-upload-card-area { + grid-column: 1 / -1; + align-items: stretch; + + &:before { + display: none; + } + } + + .fl-asst-media-app-list-endcap { + background: none; + grid-column: 1 / -1; + min-height: 80px; + padding: 30px; + display: flex; + align-items: center; + justify-content: center; + + &:before { + display: none; + } + } +} +.fluid-frame-size-medium { + ul.fl-asst-media-app-list { + max-width: 688px; + margin: 0 auto; + padding: 30px; + padding-top: 0; + grid-gap: 30px; + } +} diff --git a/src/apps/fl-media/ui/shell/index.js b/src/apps/fl-media/ui/shell/index.js new file mode 100644 index 000000000..9d24fb2e1 --- /dev/null +++ b/src/apps/fl-media/ui/shell/index.js @@ -0,0 +1,103 @@ +import React from 'react' +import { __ } from '@wordpress/i18n' +import c from 'classnames' +import { Layout, Button, Icon } from 'assistant/ui' +import { getSystemHooks } from 'assistant/data' +import { attachmentTypes, useMediaApp } from '../../data' +import MediaIcon from '../../icon' +import './style.scss' + +const MediaShell = ( { children, className, ...rest } ) => { + const { showUploader, setShowUploader } = useMediaApp() + return ( +
    + + + + + +
    +
    +
    + + { __( 'Media', 'fl-assistant' ) } +
    +
    +
    +
    +
    +
    {children}
    +
    + ) +} + +const AttachmentTypesSection = () => { + const { query, setQuery } = useMediaApp() + const setType = value => setQuery( { ...query, post_mime_type: value, label: '' } ) + + return ( + +
      + { Object.keys( attachmentTypes ).map( key => { + const { label, icon: TypeIcon } = attachmentTypes[ key ] + + return ( +
    • + +
    • + ) + } ) } +
    +
    + ) +} + +const LabelsSection = () => { + const { query, setQuery } = useMediaApp() + const { useLabels } = getSystemHooks() + const [ labels ] = useLabels() + + const LabelDot = ( { color } ) => ( +
    + ) + + return ( + +
      + { labels.map( item => { + const { id, label, color } = item + return ( +
    • + +
    • + ) + } ) } +
    +
    + ) +} + +export default MediaShell diff --git a/src/apps/fl-media/ui/shell/style.scss b/src/apps/fl-media/ui/shell/style.scss new file mode 100644 index 000000000..936b145bf --- /dev/null +++ b/src/apps/fl-media/ui/shell/style.scss @@ -0,0 +1,72 @@ +.fl-asst-media-app-shell { + flex: 1 1 auto; + display: grid; + grid-template-rows: minmax( 80px, auto ) 1fr; + min-height: 0; + max-height: 100%; + + .fl-asst-toolbar { + grid-row: 1 / 2; + grid-column: 1 / -1; + display: flex; + + .fl-asst-primary-toolbar-area, + .fl-asst-secondary-toolbar-area { + flex: 1 1 auto; + display: flex; + align-items: center; + z-index: 1; + padding: 20px; + } + .fl-asst-primary-toolbar-area { + padding-left: 25px; // Logo offset + } + .fl-asst-secondary-toolbar-area { + justify-content: flex-end; + } + .fl-asst-media-branding { + display: flex; + font-size: 18px; + + svg { + margin-right: 13px; + } + } + } + + .fl-asst-media-app-content { + grid-row: 2 / -1; + grid-column: 1 / -1; + display: flex; + flex-direction: column; + + /* Scroller stuff */ + min-height: 0; + max-height: 100%; + overflow: auto; + } +} + +.fluid-frame-size-medium { + .fl-asst-media-app-shell { + grid-template-columns: minmax( 120px, 220px ) 1fr; + + .fl-asst-toolbar { + display: contents; /* promote children to grid items */ + + .fl-asst-primary-toolbar-area { + grid-row: 1 / 2; + grid-column: 1 / 2; + } + .fl-asst-secondary-toolbar-area { + grid-row: 1 / 2; + grid-column: 2 / -1; + } + } + + .fl-asst-media-app-content { + grid-row: 2 / -1; + grid-column: 2 / -1; + } + } +} diff --git a/src/apps/fl-media/style.scss b/src/apps/fl-media/ui/style.scss similarity index 100% rename from src/apps/fl-media/style.scss rename to src/apps/fl-media/ui/style.scss diff --git a/src/apps/fl-media/ui/upload-card/index.js b/src/apps/fl-media/ui/upload-card/index.js index 224b885f8..113a238a9 100644 --- a/src/apps/fl-media/ui/upload-card/index.js +++ b/src/apps/fl-media/ui/upload-card/index.js @@ -9,30 +9,28 @@ const UploadCard = ( { ...rest } ) => { return ( -
    -
    - -
    +
    + +
    ) } diff --git a/src/apps/fl-media/ui/upload-card/style.scss b/src/apps/fl-media/ui/upload-card/style.scss index e392471c3..e95178f69 100644 --- a/src/apps/fl-media/ui/upload-card/style.scss +++ b/src/apps/fl-media/ui/upload-card/style.scss @@ -1,9 +1,4 @@ .fl-asst { - .fl-asst-upload-card-wrapper { - max-width: 550px; - margin: 0 auto; - padding-top: 20px; - } .fl-asst-upload-card { --space-around: clamp( 10px, 4%, 40px ); @@ -13,7 +8,6 @@ background: var(--fluid-transparent-12); padding: 30px 20px 20px; border-radius: var(--fluid-radius); - margin: 0 var(--space-around); .close-action { position: absolute; diff --git a/src/render/app/index.js b/src/render/app/index.js index 21f400060..ac17e2ec5 100644 --- a/src/render/app/index.js +++ b/src/render/app/index.js @@ -9,11 +9,10 @@ import './style.scss' const AppMain = () => { const { apps, window: windowFrame, isAppHidden, homeKey } = useSystemState( [ 'apps', 'window', 'isAppHidden', 'homeKey' ] ) - const { origin, isHidden } = windowFrame + const { origin } = windowFrame const sideName = origin[0] ? 'right' : 'left' - const { isMobile, application } = Env.use() + const { isMobile } = Env.use() const rowDirection = 'right' === sideName ? 'row-reverse' : 'row' - const isBeaverBuilder = 'beaver-builder' === application const classes = classname( { 'fl-asst-main': true, @@ -32,17 +31,17 @@ const AppMain = () => { } ), } - const displayContent = ! isAppHidden && ( ! isHidden || isBeaverBuilder ) + const displayContent = ! isAppHidden return (
    - + <> { displayContent && ( { /> ) } - +
    ) } diff --git a/src/system/ui/icon/video.js b/src/system/ui/icon/video.js index 64d758648..9ba5d6cde 100644 --- a/src/system/ui/icon/video.js +++ b/src/system/ui/icon/video.js @@ -1,8 +1,9 @@ import React from 'react' const Video = () => ( - - + + + ) diff --git a/src/system/ui/layout/index.js b/src/system/ui/layout/index.js index 552bc244b..7075671be 100644 --- a/src/system/ui/layout/index.js +++ b/src/system/ui/layout/index.js @@ -3,6 +3,7 @@ import Attention from './attention' import PublishBar from './publish-bar' import Table from './table' import { Tabs, TabsToolbar, CurrentTab } from './nav' +import { SidebarBackdrop, SidebarSection } from './sidebar' const Layout = { ...FLUID_Layout, @@ -11,7 +12,9 @@ const Layout = { Table, Tabs, TabsToolbar, - CurrentTab + CurrentTab, + SidebarBackdrop, + SidebarSection, } export default Layout diff --git a/src/system/ui/layout/sidebar/index.js b/src/system/ui/layout/sidebar/index.js new file mode 100644 index 000000000..fb520c75b --- /dev/null +++ b/src/system/ui/layout/sidebar/index.js @@ -0,0 +1,32 @@ +import React from 'react' +import c from 'classnames' +import './style.scss' + +export const SidebarBackdrop = ( { className, ...rest } ) => ( +
    +) + +export const SidebarSection = ( { + title, + className, + children, + ...rest +} ) => { + + return ( +
    + { title && ( +
    + {title} +
    + ) } +
    {children}
    +
    + ) +} diff --git a/src/system/ui/layout/sidebar/style.scss b/src/system/ui/layout/sidebar/style.scss new file mode 100644 index 000000000..715918cbc --- /dev/null +++ b/src/system/ui/layout/sidebar/style.scss @@ -0,0 +1,66 @@ +.fl-asst { + .fl-asst-sidebar-backdrop { + display: none; + background: hsl( var(--fluid-hue), 33%, 97% ); /* Slightly different from --fluid-opaque-13 */ + padding-top: 80px; /* usually under toolbar */ + } + .fluid-frame-size-medium { + .fl-asst-sidebar-backdrop { + display: block; + grid-column: 1 / 2; + grid-row: 1 / -1; + } + } + .fluid-color-scheme-dark { + .fl-asst-sidebar-backdrop { + background: hsl( var(--fluid-hue), 10%, 12% ); + } + } + + + .fl-asst-sidebar-section { + padding: 15px; + + .fl-asst-sidebar-section-title { + padding: 5px var(--fluid-med-space); + } + ul { + margin: 0; + + li { + display: flex; + flex-direction: row; + + .fluid-button { + flex: 1 1 auto; + justify-content: flex-start; + background: transparent; + + .fluid-button-icon { + color: var(--fluid-accent); + margin-right: 10px; + } + + &.is-selected, + &:focus.is-selected { + background: var(--fluid-opaque-11) !important; + color: var(--fluid-blue); + } + } + } + } + } + .fluid-color-scheme-dark { + .fl-asst-sidebar-section ul li { + .fluid-button { + color: var(--fluid-opaque-8); + + &.is-selected, + &:focus.is-selected { + color: var(--fluid-opaque-14); + background: var(--fluid-opaque-3) !important; + } + } + } + } +} diff --git a/src/system/ui/media/use-media-uploads.js b/src/system/ui/media/use-media-uploads.js index c78d49611..1cbc59461 100644 --- a/src/system/ui/media/use-media-uploads.js +++ b/src/system/ui/media/use-media-uploads.js @@ -10,15 +10,15 @@ const useMediaUploads = () => { const { current, items } = useStore( key ) const { setCurrent, setItems } = getDispatch( key ) - const uploadFiles = files => { + const uploadFiles = ( files, callback = () => {} ) => { setItems( [ ...items, ...files ] ) if ( ! current ) { - uploadNext() + uploadNext( callback ) } } - const uploadNext = () => { + const uploadNext = callback => { const { current, items } = getStore( key ).getState() const file = items[current] const data = new FormData() @@ -26,6 +26,7 @@ const useMediaUploads = () => { if ( ! file ) { setItems( [] ) setCurrent( 0 ) + callback() return } @@ -38,7 +39,7 @@ const useMediaUploads = () => { } ) .finally( () => { setCurrent( current + 1 ) - uploadNext() + uploadNext( callback ) } ) } diff --git a/src/system/ui/pages/attachment/index.js b/src/system/ui/pages/attachment/index.js index d11af2111..3f228d24d 100644 --- a/src/system/ui/pages/attachment/index.js +++ b/src/system/ui/pages/attachment/index.js @@ -1,6 +1,7 @@ import React, { memo } from 'react' import { __ } from '@wordpress/i18n' import { useHistory } from 'react-router-dom' +import { motion } from 'framer-motion' import { Page, Form, Layout, Notice, Button } from 'ui' import { getSrcSet } from 'utils/image' import { getWpRest } from 'utils/wordpress' @@ -13,7 +14,7 @@ export const Attachment = () => { const wpRest = getWpRest() const { setCurrentHistoryState } = getSystemActions() const { createNotice } = Notice.useNotices() - const { id, title, type, subtype } = item + const { id, type, subtype } = item const onSubmit = ( { changed, ids } ) => { const data = { @@ -231,7 +232,7 @@ export const Attachment = () => { ) } -const Hero = memo( ( { width, sizes, height, alt, type, url, mime, thumbnail } ) => { +const Hero = memo( ( { width, sizes, height, alt, type, url, mime, thumbnail, id } ) => { const srcSet = getSrcSet( sizes ) // Temp - Handle non-image heroes. @@ -249,9 +250,12 @@ const Hero = memo( ( { width, sizes, height, alt, type, url, mime, thumbnail } ) return ( {mediaContent} diff --git a/src/system/ui/pages/detail/index.js b/src/system/ui/pages/detail/index.js index 36a79175a..fdada1004 100644 --- a/src/system/ui/pages/detail/index.js +++ b/src/system/ui/pages/detail/index.js @@ -2,7 +2,7 @@ import React from 'react' import c from 'classnames' import { useHistory } from 'react-router-dom' import { motion } from 'framer-motion' -import { Button, Icon, Text, Frame } from 'ui' +import { Button, Icon, Text, Frame, Layout } from 'ui' import './style.scss' const DetailPage = ( { @@ -22,7 +22,7 @@ const DetailPage = ( { const classes = c( 'fluid-page', 'fluid-detail-page', className ) return ( -
    +