mobile refactor

This commit is contained in:
Martina 2020-09-30 17:41:53 -07:00
parent 9e12cb402a
commit bf079ffc8a
23 changed files with 580 additions and 283 deletions

View File

@ -51,6 +51,12 @@ const REJECT_LIST = [
"data",
];
export const onMobile = () => {
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
navigator.userAgent
);
};
export const userRoute = (text) => {
if (!USERNAME_REGEX.test(text)) {
return false;

View File

@ -19,13 +19,14 @@ const STYLES_ALERT = `
display: flex;
flex-wrap: wrap;
align-items: center;
transition: top 0.25s;
@media (max-width: ${Constants.sizes.mobile}px) {
width: 100%;
padding: 12px;
top: 56px;
left: 0px;
right: 0px;
width: 100%;
}
`;
@ -139,7 +140,7 @@ export class Alert extends React.Component {
// NOTE(jim): Replaces the filecoin banner on some navigation pages.
if (this.props.filecoin) {
return (
<div css={STYLES_MESSAGE}>
<div css={STYLES_MESSAGE} style={this.props.style}>
<div css={STYLES_MESSAGE_BOX} style={{ fontSize: 14 }}>
You are on the Filecoin Testnet. Test FIL may take a moment to
reach your wallet.
@ -149,7 +150,7 @@ export class Alert extends React.Component {
}
return (
<div css={STYLES_MESSAGE}>
<div css={STYLES_MESSAGE} style={this.props.style}>
<div css={STYLES_MESSAGE_BOX} style={{ fontSize: 14 }}>
Please don't upload sensitive information to Slate yet. Private
storage is coming soon.
@ -165,7 +166,7 @@ export class Alert extends React.Component {
return (
<div
css={STYLES_INFO}
style={{ cursor: "pointer" }}
style={{ cursor: "pointer", ...this.props.style }}
onClick={() =>
this.props.onAction({
type: "SIDEBAR",

View File

@ -700,6 +700,7 @@ export default class ApplicationPage extends React.Component {
<SceneSignIn
onCreateUser={this._handleCreateUser}
onAuthenticate={this._handleAuthenticate}
onAction={this._handleAction}
/>
</WebsitePrototypeWrapper>
);

View File

@ -160,6 +160,8 @@ export default class ApplicationHeader extends React.Component {
style={{ transform: `rotate(180deg)` }}
/>
</span>
</span>
<span css={STYLES_MOBILE_HIDDEN}>
<span
css={STYLES_ICON_ELEMENT}
style={
@ -171,7 +173,8 @@ export default class ApplicationHeader extends React.Component {
>
<SVG.NavigationArrow height="24px" />
</span>
</span>
<span css={STYLES_MOBILE_HIDDEN}>
<span
css={this.state.isRefreshing ? STYLES_ROTATION : STYLES_STATIC}
style={{ marginLeft: 24 }}
@ -180,7 +183,8 @@ export default class ApplicationHeader extends React.Component {
<SVG.Refresh height="20px" />
</span>
</span>
</span>
<span css={STYLES_MOBILE_HIDDEN}>
<span
css={STYLES_ICON_ELEMENT}
style={{ marginLeft: 24 }}

View File

@ -1,6 +1,7 @@
import * as React from "react";
import * as Constants from "~/common/constants";
import * as SVG from "~/common/svg";
import * as Validations from "~/common/validations";
import { css } from "@emotion/react";
import { GlobalTooltip } from "~/components/system/components/fragments/GlobalTooltip";
@ -51,6 +52,7 @@ const STYLES_HEADER = css`
left: ${Constants.sizes.navigation}px;
right: 0;
top: 0;
transition: top 0.25s;
@media (max-width: ${Constants.sizes.mobile}px) {
left: 0;
}
@ -163,11 +165,59 @@ const STYLES_BLOCK = css`
color: rgba(0, 0, 0, 0.25);
`;
const STYLES_MOBILE_HIDDEN = css`
@media (max-width: ${Constants.sizes.mobile}px) {
display: none;
}
`;
const STYLES_MOBILE_ONLY = css`
@media (min-width: ${Constants.sizes.mobile}px) {
display: none;
}
`;
export default class ApplicationLayout extends React.Component {
_sidebar;
_navigation;
_body;
state = {
alertTop: 56,
};
componentDidMount = () => {
this.prevScrollPos = window.pageYOffset;
if (Validations.onMobile()) {
window.addEventListener("scroll", this._handleScroll);
}
};
componentWillUnmount = () => {
if (Validations.onMobile()) {
window.removeEventListener("scroll", this._handleScroll);
}
};
_handleScroll = () => {
console.log(document.getElementById("slate-mobile-alert"));
let currentScrollPos = window.pageYOffset;
if (this.prevScrollPos > currentScrollPos) {
if (document.getElementById("slate-mobile-header")) {
document.getElementById("slate-mobile-header").style.top = "0px";
}
this.setState({ alertTop: 56 });
} else {
if (currentScrollPos > 56) {
if (document.getElementById("slate-mobile-header")) {
document.getElementById("slate-mobile-header").style.top = "-56px";
}
this.setState({ alertTop: 0 });
}
}
this.prevScrollPos = currentScrollPos;
};
_handleDismiss = (e) => {
e.stopPropagation();
e.preventDefault();
@ -184,11 +234,7 @@ export default class ApplicationLayout extends React.Component {
allowedTypes={["sidebar"]}
/>
<div css={STYLES_SIDEBAR_HEADER}>
<div
css={STYLES_BLOCK}
onMouseUp={this._handleDismiss}
onTouchEnd={this._handleDismiss}
>
<div css={STYLES_BLOCK} onClick={this._handleDismiss}>
<SVG.Dismiss height="24px" />
</div>
</div>
@ -212,8 +258,16 @@ export default class ApplicationLayout extends React.Component {
</div>
<div css={STYLES_CONTENT}>
<GlobalTooltip elementRef={this._body} allowedTypes={["body"]} />
{/* <GlobalTooltip elementRef={this._body} allowedTypes={["body"]} /> */}
<GlobalTooltip allowedTypes={["body"]} />
<span css={STYLES_MOBILE_HIDDEN}>
<div css={STYLES_HEADER}>{this.props.header}</div>
</span>
<span css={STYLES_MOBILE_ONLY}>
<div css={STYLES_HEADER} id="slate-mobile-header">
{this.props.header}
</div>
</span>
<div
css={STYLES_BODY_WEB}
ref={(c) => {
@ -235,14 +289,10 @@ export default class ApplicationLayout extends React.Component {
</div>
<div css={STYLES_BODY_MOBILE}>
<Alert
id="slate-mobile-alert"
fileLoading={this.props.fileLoading}
onAction={this.props.onAction}
style={{
top: 0,
left: 0,
width: "100%",
zIndex: Constants.zindex.modal,
}}
style={{ top: this.state.alertTop }}
/>
{this.props.children}
</div>

View File

@ -124,8 +124,7 @@ const Item = (props) => {
>
<span
css={STYLES_EXPANDER}
onMouseUp={props.onToggleShow ? props.onToggleShow : null}
onTouchEnd={props.onToggleShow ? props.onToggleShow : null}
onClick={props.onToggleShow ? props.onToggleShow : null}
>
<span
css={STYLES_ICON_ELEMENT}
@ -143,14 +142,7 @@ const Item = (props) => {
</span>
<span
css={STYLES_ICON}
onMouseUp={() =>
props.onAction({
type: "NAVIGATE",
value: props.id,
data: props.data,
})
}
onTouchEnd={() =>
onClick={() =>
props.onAction({
type: "NAVIGATE",
value: props.id,
@ -169,14 +161,7 @@ const Item = (props) => {
<span
css={STYLES_CHILDREN}
children={props.children}
onMouseUp={() =>
props.onAction({
type: "NAVIGATE",
value: props.id,
data: props.data,
})
}
onTouchEnd={() =>
onClick={() =>
props.onAction({
type: "NAVIGATE",
value: props.id,
@ -267,6 +252,7 @@ export default class ApplicationNavigation extends React.Component {
return (
<div
key={each.id}
css={
each.id === "V1_NAVIGATION_ARCHIVE" ||
each.id === "V1_NAVIGATION_API"

View File

@ -15,6 +15,10 @@ const STYLES_CONTAINER = css`
padding: 32px;
max-width: 100%;
width: 100%;
@media (max-width: ${Constants.sizes.mobile}px) {
padding: 24px;
}
`;
const STYLES_DATA = css`

View File

@ -184,6 +184,12 @@ const STYLES_IMAGE_GRID = css`
display: grid;
grid-template-columns: repeat(auto-fit, minmax(214px, 1fr));
margin: 0 -27px;
@media (max-width: ${Constants.sizes.mobile}px) {
display: grid;
grid-template-columns: 1fr 1fr;
margin: 0px -12px;
}
`;
const STYLES_IMAGE_BOX = css`
@ -197,6 +203,18 @@ const STYLES_IMAGE_BOX = css`
0 0 40px 0 ${Constants.system.shadow};
cursor: pointer;
position: relative;
@media (max-width: ${Constants.sizes.mobile}px) {
width: 144px;
height: 144px;
margin: 12px auto;
}
`;
const STYLES_MOBILE_HIDDEN = css`
@media (max-width: ${Constants.sizes.mobile}px) {
display: none;
}
`;
const delay = (ms) => new Promise((resolve) => window.setTimeout(resolve, ms));
@ -601,7 +619,7 @@ export default class DataView extends React.Component {
const header = (
<div css={STYLES_HEADER_LINE}>
<TabGroup disabled tabs={["Uploads"]} style={{ margin: 0 }} />
<React.Fragment>
<span css={STYLES_MOBILE_HIDDEN}>
<div
css={STYLES_ICON_BOX}
onClick={() => {
@ -634,7 +652,7 @@ export default class DataView extends React.Component {
height="24px"
/>
</div>
</React.Fragment>
</span>
</div>
);
const footer = (
@ -738,6 +756,7 @@ export default class DataView extends React.Component {
title={each.file || each.name}
type={each.type || each.icon}
/>
<span css={STYLES_MOBILE_HIDDEN}>
{numChecked ||
this.state.hover === i ||
this.state.menu === each.id ? (
@ -759,7 +778,9 @@ export default class DataView extends React.Component {
}
>
{this.state.loading[cid] ? (
<LoaderSpinner style={{ height: 24, width: 24 }} />
<LoaderSpinner
style={{ height: 24, width: 24 }}
/>
) : (
<SVG.MoreHorizontal height="24px" />
)}
@ -831,11 +852,16 @@ export default class DataView extends React.Component {
? Constants.system.brand
: "rgba(255, 255, 255, 0.75)",
}}
style={{ position: "absolute", bottom: 8, left: 8 }}
style={{
position: "absolute",
bottom: 8,
left: 8,
}}
/>
</div>
</React.Fragment>
) : null}
</span>
</div>
);
})}

View File

@ -36,6 +36,10 @@ const STYLES_HEADER = css`
max-width: 688px;
white-space: pre-wrap;
overflow-wrap: break-word;
@media (max-width: ${Constants.sizes.mobile}px) {
font-size: ${Constants.typescale.lvl3};
}
`;
const STYLES_DESCRIPTION = css`

View File

@ -8,7 +8,6 @@ import { LoaderSpinner } from "~/components/system/components/Loaders";
const STYLES_DROPDOWN_CONTAINER = css`
box-sizing: border-box;
z-index: ${Constants.zindex.modal};
height: 100%;
`;
const STYLES_DROPDOWN = css`
@ -21,10 +20,16 @@ const STYLES_DROPDOWN = css`
width: 100%;
scrollbar-width: none;
padding-bottom: 24px;
height: calc(100% - 16px);
overflow-y: scroll;
::-webkit-scrollbar {
display: none;
}
@media (max-width: ${Constants.sizes.mobile}px) {
height: calc(100% - 36px);
}
`;
const STYLES_DROPDOWN_ITEM = css`

View File

@ -30,6 +30,11 @@ const STYLES_CONTAINER = css`
border-radius: 4px;
background-color: ${Constants.system.white};
box-shadow: 0 0 60px 8px rgba(0, 0, 0, 0.03);
@media (max-width: ${Constants.sizes.mobile}px) {
max-width: 95vw;
padding: 20px;
}
`;
const STYLES_MODAL = css`
@ -42,8 +47,8 @@ const STYLES_MODAL = css`
`;
const STYLES_SEARCH_DROPDOWN = {
height: "calc(100% - 16px)",
overflowY: "scroll",
// height: "calc(100% - 16px)",
// overflowY: "scroll",
};
const STYLES_USER_ENTRY_CONTAINER = css`

View File

@ -2,6 +2,7 @@ import * as React from "react";
import * as Constants from "~/common/constants";
import * as SVG from "~/common/svg";
import * as Strings from "~/common/strings";
import * as Validations from "~/common/validations";
import * as Actions from "~/common/actions";
import { Responsive, WidthProvider } from "react-grid-layout";
@ -88,6 +89,12 @@ const STYLES_ACTION_BUTTON = css`
}
`;
const STYLES_MOBILE_HIDDEN = css`
@media (max-width: ${Constants.sizes.mobile}px) {
display: none;
}
`;
const ResponsiveReactGridLayout = WidthProvider(Responsive);
const COLUMN_MAP = { lg: 12, md: 8, sm: 6, xs: 4, xxs: 2 };
@ -178,16 +185,25 @@ export default class Slate extends React.Component {
}
return (
<div key={index} css={STYLES_ITEM}>
<div
key={index}
css={STYLES_ITEM}
onClick={
Validations.onMobile()
? (e) => this._handleSelect(e, index)
: () => {}
}
>
<SlateMediaObjectPreview
charCap={70}
type={data.type}
url={data.url}
title={data.title || data.name}
/>
<span css={STYLES_MOBILE_HIDDEN}>
<figure css={STYLES_BUTTON}>
<CircleButtonGray
style={{ margin: 8 }}
style={{ margin: 8, cursor: "pointer" }}
onMouseUp={(e) => this._handleSelect(e, index)}
onTouchEnd={(e) => this._handleSelect(e, index)}
>
@ -204,6 +220,7 @@ export default class Slate extends React.Component {
</CircleButtonGray>
) : null}
</figure>
</span>
</div>
);
});
@ -245,8 +262,7 @@ export default class Slate extends React.Component {
</span>
<span
css={STYLES_ACTION_BUTTON}
onMouseUp={this._handleSaveLayout}
onTouchEnd={this._handleSaveLayout}
onClick={this._handleSaveLayout}
style={{
backgroundColor:
this.props.saving === "IDLE" ? Constants.system.brand : null,

View File

@ -5,6 +5,14 @@ import * as SVG from "~/common/svg";
import { css } from "@emotion/react";
import { FileTypeIcon } from "~/components/core/FileTypeIcon";
const STYLES_IMAGE_CONTAINER = css`
background-color: ${Constants.system.foreground};
width: 100%;
height: 100%;
background-size: cover;
background-position: 50% 50%;
`;
const STYLES_IMAGE = css`
background-color: ${Constants.system.foreground};
display: block;
@ -53,6 +61,14 @@ export default class SlateMediaObjectPreview extends React.Component {
: this.props.title;
if (this.props.type && this.props.type.startsWith("image/")) {
if (this.props.centeredImage) {
return (
<div
css={STYLES_IMAGE_CONTAINER}
style={{ backgroundImage: `url(${url})`, ...this.props.imageStyle }}
/>
);
}
return <img css={STYLES_IMAGE} style={this.props.imageStyle} src={url} />;
}

View File

@ -323,8 +323,7 @@ export default class SlateMediaObjectSidebar extends React.Component {
<span
key="sidebar-media-object-delete"
css={STYLES_BUTTON}
onMouseUp={() => this.props.onDelete(this.props.id)}
onTouchEnd={() => this.props.onDelete(this.props.id)}
onClick={() => this.props.onDelete(this.props.id)}
>
{this.props.loading ? (
<LoaderSpinner style={{ height: 16, width: 16 }} />

View File

@ -11,6 +11,18 @@ import { dispatchCustomEvent } from "~/common/custom-events";
import SlateMediaObjectPreview from "~/components/core/SlateMediaObjectPreview";
const STYLES_MOBILE_HIDDEN = css`
@media (max-width: ${Constants.sizes.mobile}px) {
display: none;
}
`;
const STYLES_MOBILE_ONLY = css`
@media (min-width: ${Constants.sizes.mobile}px) {
display: none;
}
`;
const STYLES_CREATE_NEW = css`
color: ${Constants.system.darkGray};
box-shadow: 0px 0px 0px 1px rgba(229, 229, 229, 0.5) inset;
@ -23,7 +35,10 @@ const STYLES_CREATE_NEW = css`
margin: 0px 12px;
@media (max-width: ${Constants.sizes.mobile}px) {
margin: 0 8px;
margin: 0;
border-radius: 8;
width: 100%;
height: 100%;
}
`;
@ -161,6 +176,11 @@ const STYLES_BLOCK = css`
margin: 24px auto 48px auto;
max-width: ${Constants.sizes.desktop}px;
cursor: pointer;
@media (max-width: ${Constants.sizes.mobile}px) {
padding: 16px;
margin: 24px auto;
}
`;
const STYLES_TITLE_LINE = css`
@ -170,6 +190,10 @@ const STYLES_TITLE_LINE = css`
font-size: ${Constants.typescale.lvl1};
margin-bottom: 16px;
overflow-wrap: break-word;
@media (max-width: ${Constants.sizes.mobile}px) {
display: none;
}
`;
const STYLES_COPY_INPUT = css`
@ -195,6 +219,10 @@ const STYLES_BODY = css`
line-height: 20px;
white-space: pre-wrap;
word-wrap: break-word;
@media (max-width: ${Constants.sizes.mobile}px) {
display: none;
}
`;
const STYLES_ICON_BOX = css`
@ -227,6 +255,20 @@ export default class SlatePreviewBlock extends React.Component {
state = {
showMenu: false,
copyValue: "",
windowWidth: 360,
};
componentDidMount = () => {
this.calculateWidth();
window.addEventListener("resize", this.calculateWidth);
};
componentWillUnmount = () => {
window.removeEventListener("resize", this.calculateWidth);
};
calculateWidth = () => {
this.setState({ windowWidth: window.innerWidth });
};
_handleCopy = (e, value) => {
@ -267,6 +309,9 @@ export default class SlatePreviewBlock extends React.Component {
if (!this.props.editing && !this.props.slate.data.objects.length) {
return null;
}
let first = this.props.slate.data.objects
? this.props.slate.data.objects[0]
: null;
let contextMenu = (
<React.Fragment>
<Boundary
@ -387,10 +432,47 @@ export default class SlatePreviewBlock extends React.Component {
) : (
<div style={{ height: "8px" }} />
)}
<span css={STYLES_MOBILE_ONLY}>
<div
css={STYLES_TITLE}
style={{ marginBottom: 8, fontSize: Constants.typescale.lvl1 }}
>
{this.props.slate.data.name}
</div>
<div style={{ marginBottom: 16, fontSize: 12 }}>
{this.props.slate.data.objects.length} Object
{this.props.slate.data.objects.length === 1 ? "" : "s"}
</div>
<div
style={{
width: "100%",
height: `${this.state.windowWidth - 80}px`,
}}
>
{first ? (
<SlateMediaObjectPreview
centeredImage
charCap={30}
type={first.type}
url={first.url}
style={{ borderRadius: 8 }}
imageStyle={{ borderRadius: 8 }}
title={first.title || first.name}
/>
) : (
<div css={STYLES_CREATE_NEW} key="add-files">
<SVG.Plus height="24px" />
<div>Add Files</div>
</div>
)}
</div>
</span>
<span css={STYLES_MOBILE_HIDDEN}>
<SlatePreviewRow
{...this.props}
previewStyle={this.props.previewStyle}
/>
</span>
</div>
);
}

View File

@ -11,6 +11,11 @@ const STYLES_TAB_GROUP = css`
flex-direction: row;
box-sizing: border-box;
width: 100%;
flex-wrap: wrap;
@media (max-width: ${Constants.sizes.mobile}px) {
margin: 24px 0px 24px 0px;
}
`;
const STYLES_TAB = css`
@ -23,6 +28,7 @@ const STYLES_TAB = css`
@media (max-width: ${Constants.sizes.mobile}px) {
margin-right: 12px;
font-size: ${Constants.typescale.lvl1};
}
`;

View File

@ -87,6 +87,34 @@ const STYLES_EXPANDER = css`
}
`;
const STYLES_DISMISS_BOX = css`
position: absolute;
top: 16px;
right: 16px;
color: ${Constants.system.darkGray};
cursor: pointer;
:hover {
color: ${Constants.system.black};
}
@media (min-width: ${Constants.sizes.mobile}px) {
display: none;
}
`;
const STYLES_MOBILE_HIDDEN = css`
@media (max-width: ${Constants.sizes.mobile}px) {
display: none;
}
`;
const STYLES_MOBILE_ONLY = css`
@media (min-width: ${Constants.sizes.mobile}px) {
display: none;
}
`;
export class GlobalViewerCID extends React.Component {
state = {
index: 0,
@ -156,8 +184,11 @@ export class GlobalViewerCID extends React.Component {
});
};
_handleClose = () =>
_handleClose = (e) => {
e.stopPropagation();
e.preventDefault();
this.setState({ visible: false, index: 0, loading: false, saving: false });
};
_handleCreate = (e) => {
const shouldPersist =
@ -202,21 +233,20 @@ export class GlobalViewerCID extends React.Component {
<div css={STYLES_ROOT_CONTENT} style={this.props.style}>
<span
css={STYLES_BOX}
onMouseUp={this._handlePrevious}
onTouchEnd={this._handlePrevious}
onClick={this._handlePrevious}
style={{ top: 0, left: 16, bottom: 0 }}
>
<SVG.ChevronLeft height="20px" />
</span>
<span
css={STYLES_BOX}
onMouseUp={this._handleNext}
onTouchEnd={this._handleNext}
onClick={this._handleNext}
style={{ top: 0, right: 16, bottom: 0 }}
>
<SVG.ChevronRight height="20px" />
</span>
{current.component}
<span css={STYLES_MOBILE_HIDDEN}>
<div
css={STYLES_EXPANDER}
onClick={() =>
@ -229,7 +259,12 @@ export class GlobalViewerCID extends React.Component {
<SVG.Minimize height="24px" />
)}
</div>
</span>
<div css={STYLES_DISMISS_BOX} onClick={this._handleClose}>
<SVG.Dismiss height="24px" />
</div>
</div>
<span css={STYLES_MOBILE_HIDDEN}>
<GlobalViewerCIDSidebar
display={this.state.showSidebar ? "block" : "none"}
onClose={this._handleClose}
@ -240,6 +275,7 @@ export class GlobalViewerCID extends React.Component {
onAction={this.props.onAction}
{...current}
/>
</span>
</div>
);
}

View File

@ -116,12 +116,7 @@ export default class GlobalViewerCIDSidebar extends React.Component {
if (this.props.onClose) {
elements.push(
<div
key="s-1"
css={STYLES_DISMISS_BOX}
onMouseUp={this.props.onClose}
onTouchEnd={this.props.onClose}
>
<div key="s-1" css={STYLES_DISMISS_BOX} onClick={this.props.onClose}>
<SVG.Dismiss height="24px" />
</div>
);

View File

@ -78,8 +78,7 @@ export const ButtonPrimary = (props) => {
children={props.children}
type={props.label}
htmlFor={props.htmlFor}
onMouseUp={props.onClick}
onTouchEnd={props.onClick}
onClick={props.onClick}
/>
);
}
@ -92,8 +91,7 @@ export const ButtonPrimary = (props) => {
: STYLES_BUTTON_PRIMARY
}
style={{ ...props.style, width: props.full ? "100%" : "auto" }}
onMouseUp={props.onClick}
onTouchEnd={props.onClick}
onClick={props.onClick}
children={props.children}
/>
);
@ -153,8 +151,7 @@ export const ButtonSecondary = (props) => {
: STYLES_BUTTON_SECONDARY
}
style={{ ...props.style, width: props.full ? "100%" : "auto" }}
onMouseUp={props.onClick}
onTouchEnd={props.onClick}
onClick={props.onClick}
children={props.children}
type={props.label}
htmlFor={props.htmlFor}
@ -169,8 +166,7 @@ export const ButtonSecondary = (props) => {
? STYLES_BUTTON_SECONDARY_TRANSPARENT
: STYLES_BUTTON_SECONDARY
}
onMouseUp={props.onClick}
onTouchEnd={props.onClick}
onClick={props.onClick}
children={props.children}
style={{ ...props.style, width: props.full ? "100%" : "auto" }}
/>
@ -208,8 +204,7 @@ export const ButtonDisabled = (props) => {
? STYLES_BUTTON_DISABLED_TRANSPARENT
: STYLES_BUTTON_DISABLED
}
onMouseUp={props.onClick}
onTouchEnd={props.onClick}
onClick={props.onClick}
children={props.children}
type={props.label}
htmlFor={props.htmlFor}
@ -275,8 +270,7 @@ export const ButtonWarning = (props) => {
children={props.children}
type={props.label}
htmlFor={props.htmlFor}
onMouseUp={props.onClick}
onTouchEnd={props.onClick}
onClick={props.onClick}
/>
);
}
@ -289,8 +283,7 @@ export const ButtonWarning = (props) => {
: STYLES_BUTTON_WARNING
}
style={{ ...props.style, width: props.full ? "100%" : "auto" }}
onMouseUp={props.onClick}
onTouchEnd={props.onClick}
onClick={props.onClick}
children={props.children}
/>
);

View File

@ -36,6 +36,10 @@ const STYLES_USER = css`
color: ${Constants.system.brand};
font-family: ${Constants.font.medium};
font-size: ${Constants.typescale.lvl1};
@media (max-width: ${Constants.sizes.mobile}px) {
margin: 12px 16px;
}
`;
const STYLES_BUTTONS = css`
@ -43,6 +47,11 @@ const STYLES_BUTTONS = css`
display: flex;
flex-direction: row;
margin-right: 48px;
justify-content: flex-end;
@media (max-width: ${Constants.sizes.mobile}px) {
margin-right: 8px;
}
`;
const STYLES_ITEM_BOX = css`
@ -54,6 +63,10 @@ const STYLES_ITEM_BOX = css`
padding: 8px;
margin-right: 48px;
color: ${Constants.system.darkGray};
@media (max-width: ${Constants.sizes.mobile}px) {
margin-right: 8px;
}
`;
const STYLES_ACTION_BUTTON = css`
@ -114,6 +127,18 @@ const STYLES_COPY_INPUT = css`
opacity: 0;
`;
const STYLES_MOBILE_HIDDEN = css`
@media (max-width: ${Constants.sizes.mobile}px) {
display: none;
}
`;
const STYLES_MOBILE_ONLY = css`
@media (min-width: ${Constants.sizes.mobile}px) {
display: none;
}
`;
export default class SceneDirectory extends React.Component {
_ref;
@ -180,6 +205,33 @@ export default class SceneDirectory extends React.Component {
})
.map((relation) => {
let button = (
<React.Fragment>
<span css={STYLES_MOBILE_ONLY}>
<div css={STYLES_BUTTONS}>
<div
css={STYLES_ITEM_BOX}
onClick={(e) => this._handleAccept(e, relation.owner.id)}
>
<SVG.CheckBox
height="24px"
style={{ color: Constants.system.brand }}
/>
</div>
<div
css={STYLES_ITEM_BOX}
style={{ marginRight: 0 }}
onClick={(e) => {
this._handleDelete(e, relation.id);
}}
>
<SVG.Dismiss
height="24px"
style={{ color: Constants.system.gray }}
/>
</div>
</div>
</span>
<span css={STYLES_MOBILE_HIDDEN}>
<div css={STYLES_BUTTONS}>
<ButtonPrimary
transparent
@ -198,6 +250,8 @@ export default class SceneDirectory extends React.Component {
Decline
</ButtonSecondary>
</div>
</span>
</React.Fragment>
);
return (
<UserEntry

View File

@ -45,10 +45,7 @@ export default class SceneFilesFolder extends React.Component {
/>
<TabGroup disabled tabs={["Usage"]} />
<DataMeter
stats={this.props.viewer.stats}
style={{ margin: "48px 0 48px 0" }}
/>
<DataMeter stats={this.props.viewer.stats} />
{this.props.viewer.library[0].children &&
this.props.viewer.library[0].children.length ? (
<DataView

View File

@ -2,6 +2,7 @@ import * as React from "react";
import * as System from "~/components/system";
import * as Actions from "~/common/actions";
import * as Constants from "~/common/constants";
import * as Validations from "~/common/validations";
import * as SVG from "~/common/svg";
import * as Strings from "~/common/strings";
import * as Window from "~/common/window";
@ -27,6 +28,12 @@ const STYLES_ICONS = css`
justify-content: center;
`;
const STYLES_ACTIONS = css`
@media (max-width: ${Constants.sizes.mobile}px) {
padding-left: 24px;
}
`;
const STYLES_USERNAME = css`
cursor: pointer;
@ -35,6 +42,18 @@ const STYLES_USERNAME = css`
}
`;
const STYLES_MOBILE_HIDDEN = css`
@media (max-width: ${Constants.sizes.mobile}px) {
display: none;
}
`;
const STYLES_MOBILE_ONLY = css`
@media (min-width: ${Constants.sizes.mobile}px) {
display: none;
}
`;
const moveIndex = (set, fromIndex, toIndex) => {
const element = set[fromIndex];
set.splice(fromIndex, 1);
@ -416,6 +435,45 @@ export default class SceneSlate extends React.Component {
return subscription.target_slate_id === this.props.current.id;
}).length;
let onMobile = Validations.onMobile();
let actions = this.state.editing ? (
<span css={STYLES_ACTIONS}>
<CircleButtonGray onClick={this._handleAdd} style={{ marginRight: 16 }}>
<SVG.Plus height="16px" />
</CircleButtonGray>
{isPublic ? (
<CircleButtonGray
onClick={() => this._handleSlateLink()}
style={{ marginRight: 16 }}
>
<SVG.DeepLink height="16px" />
</CircleButtonGray>
) : null}
<CircleButtonGray onClick={this._handleShowSettings}>
<SVG.Settings height="16px" />
</CircleButtonGray>
</span>
) : (
<div onClick={this._handleFollow}>
{following ? (
<ButtonSecondary
transparent
style={{ minWidth: 120, paddingLeft: 0 }}
loading={this.state.followLoading}
>
Unfollow
</ButtonSecondary>
) : (
<ButtonPrimary
transparent
style={{ minWidth: 120, paddingLeft: 0 }}
loading={this.state.followLoading}
>
Follow
</ButtonPrimary>
)}
</div>
);
return (
<ScenePage
style={{ paddingLeft: "24px", paddingRight: "24px" }}
@ -445,61 +503,15 @@ export default class SceneSlate extends React.Component {
data.name
)
}
actions={
this.state.editing ? (
<React.Fragment>
<CircleButtonGray
onMouseUp={this._handleAdd}
onTouchEnd={this._handleAdd}
style={{ marginRight: 16 }}
>
<SVG.Plus height="16px" />
</CircleButtonGray>
{isPublic ? (
<CircleButtonGray
onMouseUp={() => this._handleSlateLink()}
onTouchEnd={() => this._handleSlateLink()}
style={{ marginRight: 16 }}
>
<SVG.DeepLink height="16px" />
</CircleButtonGray>
) : null}
<CircleButtonGray
onMouseUp={this._handleShowSettings}
onTouchEnd={this._handleShowSettings}
>
<SVG.Settings height="16px" />
</CircleButtonGray>
</React.Fragment>
) : (
<div onClick={this._handleFollow}>
{following ? (
<ButtonSecondary
transparent
style={{ minWidth: 120 }}
loading={this.state.followLoading}
>
Unfollow
</ButtonSecondary>
) : (
<ButtonPrimary
transparent
style={{ minWidth: 120 }}
loading={this.state.followLoading}
>
Follow
</ButtonPrimary>
)}
</div>
)
}
actions={<span css={STYLES_MOBILE_HIDDEN}>actions</span>}
>
<ProcessedText text={body} />
</ScenePageHeader>
<span css={STYLES_MOBILE_ONLY}>{actions}</span>
{objects && objects.length ? (
layouts ? (
<Slate
editing={this.state.editing}
editing={onMobile ? false : this.state.editing}
saving={this.state.saving}
items={objects}
layouts={layouts}

View File

@ -72,8 +72,7 @@ export default class SceneSlates extends React.Component {
actions={
this.state.tab === 0 ? (
<CircleButtonGray
onMouseUp={this._handleAdd}
onTouchEnd={this._handleAdd}
onClick={this._handleAdd}
style={{ marginLeft: 12 }}
>
<SVG.Plus height="16px" />