removed peers from ui

This commit is contained in:
Martina 2020-12-12 17:16:55 -08:00
parent 31642ede5a
commit fa7e91d1b6
6 changed files with 286 additions and 384 deletions

View File

@ -28,6 +28,7 @@ const STYLES_PROFILE = css`
`;
const STYLES_PROFILE_INFO = css`
padding: 32px 32px 0px 32px;
display: flex;
line-height: 1.3;
width: 50%;
@ -59,21 +60,8 @@ const STYLES_INFO_INTERNAL = css`
}
`;
const STYLES_INFO = css`
display: block;
width: 100%;
max-width: calc(100% - 224px);
text-align: left;
margin-bottom: 48px;
overflow-wrap: break-word;
white-space: pre-wrap;
@media (max-width: ${Constants.sizes.mobile}px) {
max-width: calc(100% - 80px);
}
`;
const STYLES_PROFILE_IMAGE = css`
background-color: ${Constants.system.foreground};
background-color: ${Constants.system.white};
background-size: cover;
background-position: 50% 50%;
width: 80px;
@ -88,17 +76,6 @@ const STYLES_PROFILE_IMAGE = css`
}
`;
const STYLES_NAME = css`
font-size: ${Constants.typescale.lvl3};
font-family: ${Constants.font.medium};
max-width: 100%;
font-weight: 400;
margin: 8px 24px 0px 0;
overflow-wrap: break-word;
white-space: pre-wrap;
color: ${Constants.system.black};
`;
const STYLES_NAME_INTERNAL = css`
font-size: ${Constants.typescale.lvl3};
font-family: ${Constants.font.semiBold};
@ -138,29 +115,6 @@ const STYLES_STAT = css`
flex-shrink: 0;
`;
const STYLES_BUTTON = css`
width: 96px;
height: 36px;
border-radius: 4px;
border: 1px solid ${Constants.system.gray};
padding: 8px 16px;
cursor: pointer;
margin-top: 8px;
font-family: ${Constants.font.medium};
font-weight: 400;
font-size: 14px;
text-align: center;
text-decoration: none;
color: ${Constants.system.black};
:hover {
background-color: ${Constants.system.gray};
transition: 200ms background-color linear;
}
:visited {
color: ${Constants.system.black};
}
`;
const STYLES_FLEX = css`
display: flex;
align-items: center;
@ -180,6 +134,7 @@ export default class Profile extends React.Component {
};
render() {
const external = !this.props.onAction;
let data = this.props.creator ? this.props.creator : this.props.data;
let exploreSlates = this.props.exploreSlates;
@ -189,75 +144,36 @@ export default class Profile extends React.Component {
}
return (
<div>
{this.props.onAction ? (
<div css={STYLES_PROFILE_INFO_INTERNAL}>
<div
css={STYLES_PROFILE_IMAGE}
style={{ backgroundImage: `url('${data.data.photo}')` }}
/>
<div css={STYLES_INFO_INTERNAL}>
<div css={STYLES_FLEX} style={{ marginTop: 8 }}>
<div css={STYLES_NAME_INTERNAL}>{Strings.getPresentationName(data)}</div>
<div>{this.props.buttons}</div>
</div>
<div css={STYLES_STATS}>
<div css={STYLES_STAT}>
<div style={{ fontFamily: `${Constants.font.text}` }}>
{total}{" "}
<span style={{ color: `${Constants.system.darkGray}` }}>Public data</span>
</div>
</div>
<div css={STYLES_STAT}>
<div style={{ fontFamily: `${Constants.font.text}` }}>
{data.slates.length}{" "}
<span style={{ color: `${Constants.system.darkGray}` }}>Public slates</span>
</div>
</div>
</div>
{data.data.body ? (
<div css={STYLES_DESCRIPTION}>
<ProcessedText text={data.data.body} />
</div>
) : null}
<div css={external ? STYLES_PROFILE_INFO : STYLES_PROFILE_INFO_INTERNAL}>
<div
css={STYLES_PROFILE_IMAGE}
style={{ backgroundImage: `url('${data.data.photo}')` }}
/>
<div css={STYLES_INFO_INTERNAL}>
<div css={STYLES_FLEX} style={{ marginTop: 8 }}>
<div css={STYLES_NAME_INTERNAL}>{Strings.getPresentationName(data)}</div>
<div>{this.props.buttons}</div>
</div>
</div>
) : (
<div css={STYLES_PROFILE}>
<div css={STYLES_PROFILE_INFO}>
<div
css={STYLES_PROFILE_IMAGE}
style={{ backgroundImage: `url('${data.data.photo}')` }}
/>
<div css={STYLES_INFO}>
<div css={STYLES_FLEX}>
<div css={STYLES_NAME}>{Strings.getPresentationName(data)}</div>
<a css={STYLES_BUTTON} href={"http://slate.host/_"}>
Follow
</a>
<div css={STYLES_STATS}>
<div css={STYLES_STAT}>
<div style={{ fontFamily: `${Constants.font.text}` }}>
{total} <span style={{ color: `${Constants.system.darkGray}` }}>Public data</span>
</div>
<div css={STYLES_STATS}>
<div css={STYLES_STAT}>
<div style={{ fontFamily: `${Constants.font.text}` }}>
{total}{" "}
<span style={{ color: `${Constants.system.darkGray}` }}>Public data</span>
</div>
</div>
<div css={STYLES_STAT}>
<div style={{ fontFamily: `${Constants.font.text}` }}>
{data.slates.length}{" "}
<span style={{ color: `${Constants.system.darkGray}` }}>Public slates</span>
</div>
</div>
</div>
<div css={STYLES_STAT}>
<div style={{ fontFamily: `${Constants.font.text}` }}>
{data.slates.length}{" "}
<span style={{ color: `${Constants.system.darkGray}` }}>Public slates</span>
</div>
{data.data.body ? (
<div css={STYLES_DESCRIPTION} style={{ marginBottom: 16 }}>
<ProcessedText text={data.data.body} />
</div>
) : null}
</div>
</div>
{data.data.body ? (
<div css={STYLES_DESCRIPTION}>
<ProcessedText text={data.data.body} />
</div>
) : null}
</div>
)}
</div>
{this.state.visible && (
<div>

View File

@ -584,8 +584,9 @@ export default class SlatePreviewBlocks extends React.Component {
<div css={STYLES_SLATES}>
{this.props.external
? this.props.slates.map((slate) => (
<div
<a
key={slate.id}
style={{ textDecoration: "none", color: Constants.system.black }}
href={
this.props.username
? `/${this.props.username}/${slate.slatename}`
@ -598,7 +599,7 @@ export default class SlatePreviewBlocks extends React.Component {
slate={slate}
external={this.props.external}
/>
</div>
</a>
))
: this.props.slates.map((slate) => (
<div

View File

@ -3,12 +3,13 @@ import * as Constants from "~/common/constants";
import * as Strings from "~/common/strings";
import { css } from "@emotion/react";
import { Alert } from "~/components/core/Alert";
import { ButtonSecondary } from "~/components/system/components/Buttons";
import Profile from "~/components/core/Profile";
import WebsitePrototypeWrapper from "~/components/core/WebsitePrototypeWrapper";
import WebsitePrototypeHeader from "~/components/core/WebsitePrototypeHeader";
import WebsitePrototypeFooter from "~/components/core/WebsitePrototypeFooter";
import CTATransition from "~/components/core/CTATransition";
const DEFAULT_IMAGE =
"https://slate.textile.io/ipfs/bafkreiaow45dlq5xaydaeqocdxvffudibrzh2c6qandpqkb6t3ahbvh6re";
@ -29,11 +30,18 @@ const STYLES_ROOT = css`
`;
export default class ProfilePage extends React.Component {
state = {
visible: false,
};
render() {
const title = this.props.creator ? `${this.props.creator.username}` : "404";
const url = `https://slate.host/${title}`;
const description = this.props.creator.data.body;
const image = this.props.creator.data.photo;
const buttons = (
<ButtonSecondary onClick={() => this.setState({ visible: true })}>Follow</ButtonSecondary>
);
if (Strings.isEmpty(image)) {
image = DEFAULT_IMAGE;
@ -43,8 +51,21 @@ export default class ProfilePage extends React.Component {
<WebsitePrototypeWrapper title={title} description={description} url={url} image={image}>
<WebsitePrototypeHeader />
<div css={STYLES_ROOT}>
<Profile {...this.props} />
<Profile {...this.props} buttons={buttons} />
</div>
{this.state.visible && (
<div>
<CTATransition
onClose={() => this.setState({ visible: false })}
viewer={this.props.viewer}
open={this.state.visible}
redirectURL={`/_${Strings.createQueryParams({
scene: "V1_NAVIGATION_PROFILE",
user: this.props.creator.username,
})}`}
/>
</div>
)}
<WebsitePrototypeFooter />
</WebsitePrototypeWrapper>
);

View File

@ -7,8 +7,8 @@ import * as Actions from "~/common/actions";
import * as Validations from "~/common/validations";
import * as Events from "~/common/custom-events";
import { ButtonSecondary } from "~/components/system/components/Buttons";
import { css } from "@emotion/react";
import { Alert } from "~/components/core/Alert";
import { ViewAllButton } from "~/components/core/ViewAll";
import { SlateLayout } from "~/components/core/SlateLayout";
import { SlateLayoutMobile } from "~/components/core/SlateLayoutMobile";
@ -59,6 +59,7 @@ const STYLES_SLATE_INTRO = css`
const STYLES_TITLELINE = css`
display: flex;
align-items: flex-end;
line-height: 1.3;
word-wrap: break-word;
@ -121,42 +122,6 @@ const STYLES_STAT = css`
flex-shrink: 0;
`;
const STYLES_BUTTONS = css`
display: flex;
width: 200px;
height: 36px;
border-radius: 4px;
border: 1px solid ${Constants.system.gray};
flex-shrink: 0;
@media (max-width: ${Constants.sizes.mobile}px) {
margin: 12px 0;
}
`;
const STYLES_BUTTON = css`
border-right: 1px solid ${Constants.system.gray};
padding: 8px 4px;
cursor: pointer;
width: 50%;
font-family: ${Constants.font.medium};
font-weight: 400;
font-size: 14px;
text-align: center;
text-decoration: none;
color: ${Constants.system.black};
:last-child {
border-right: none;
}
:hover {
background-color: ${Constants.system.gray};
transition: 200ms background-color linear;
}
:visited {
color: ${Constants.system.black};
}
`;
const STYLES_SLATE = css`
padding: 0 32px;
display: block;
@ -321,14 +286,9 @@ export default class SlatePage extends React.Component {
{slateCreator}
</a>
<div css={STYLES_TITLE}>{slateTitle} </div>
<div css={STYLES_BUTTONS}>
<div css={STYLES_BUTTON} onClick={() => this.setState({ visible: true })}>
Follow
</div>
<div css={STYLES_BUTTON} onClick={() => this.setState({ visible: true })}>
Download
</div>
</div>
<ButtonSecondary onClick={() => this.setState({ visible: true })}>
Follow
</ButtonSecondary>
</div>
<div css={STYLES_DESCRIPTION}>
<ViewAllButton fullText={this.props.slate.data.body} maxCharacter={208}>
@ -383,7 +343,11 @@ export default class SlatePage extends React.Component {
onClose={() => this.setState({ visible: false })}
viewer={this.props.viewer}
open={this.state.visible}
redirectURL={`/_?scene=V1_NAVIGATION_SLATE&user=${this.props.creator.username}&slate=${this.props.slate.slatename}`}
redirectURL={`/_${Strings.createQueryParams({
scene: "V1_NAVIGATION_SLATE",
user: this.props.creator.username,
slate: this.props.slate.slatename,
})}`}
/>
</div>
)}

View File

@ -189,181 +189,181 @@ export default class SceneDirectory extends React.Component {
};
render() {
let requests = this.props.viewer.pendingTrusted
.filter((relation) => {
return !relation.data.verified;
})
.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
style={{ fontSize: 16 }}
onClick={(e) => this._handleAccept(e, relation.owner.id)}
>
Accept
</ButtonPrimary>
<ButtonSecondary
transparent
style={{ fontSize: 16 }}
onClick={(e) => {
this._handleDelete(e, relation.id);
}}
>
Decline
</ButtonSecondary>
</div>
</span>
</React.Fragment>
);
return (
<UserEntry
key={relation.id}
user={relation.owner}
button={button}
onClick={() => {
this.props.onAction({
type: "NAVIGATE",
value: this.props.sceneId,
scene: "PUBLIC_PROFILE",
data: relation.owner,
});
}}
message=" requested to trust you"
/>
);
});
// let requests = this.props.viewer.pendingTrusted
// .filter((relation) => {
// return !relation.data.verified;
// })
// .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
// style={{ fontSize: 16 }}
// onClick={(e) => this._handleAccept(e, relation.owner.id)}
// >
// Accept
// </ButtonPrimary>
// <ButtonSecondary
// transparent
// style={{ fontSize: 16 }}
// onClick={(e) => {
// this._handleDelete(e, relation.id);
// }}
// >
// Decline
// </ButtonSecondary>
// </div>
// </span>
// </React.Fragment>
// );
// return (
// <UserEntry
// key={relation.id}
// user={relation.owner}
// button={button}
// onClick={() => {
// this.props.onAction({
// type: "NAVIGATE",
// value: this.props.sceneId,
// scene: "PUBLIC_PROFILE",
// data: relation.owner,
// });
// }}
// message=" requested to trust you"
// />
// );
// });
let trusted = this.props.viewer.pendingTrusted
.filter((relation) => {
return relation.data.verified;
})
.map((relation) => {
let button = (
<div css={STYLES_ITEM_BOX} onClick={(e) => this._handleClick(e, relation.id)}>
<SVG.MoreHorizontal height="24px" />
{this.state.contextMenu === relation.id ? (
<Boundary
captureResize={true}
captureScroll={false}
enabled
onOutsideRectEvent={(e) => this._handleClick(e, relation.id)}
>
<PopoverNavigation
style={{
top: "40px",
right: "0px",
}}
navigation={[
{
text: "Copy profile URL",
onClick: (e) =>
this._handleCopy(e, `https://slate.host/${relation.owner.username}`),
},
{
text: "Remove peer",
onClick: (e) => this._handleDelete(e, relation.id),
},
]}
/>
</Boundary>
) : null}
</div>
);
return (
<UserEntry
key={relation.id}
user={relation.owner}
button={button}
onClick={() => {
this.props.onAction({
type: "NAVIGATE",
value: this.props.sceneId,
scene: "PUBLIC_PROFILE",
data: relation.owner,
});
}}
/>
);
});
if (!trusted) {
trusted = [];
}
trusted.push(
...this.props.viewer.trusted
.filter((relation) => {
return relation.data.verified;
})
.map((relation) => {
let button = (
<div css={STYLES_ITEM_BOX} onClick={(e) => this._handleClick(e, relation.id)}>
<SVG.MoreHorizontal height="24px" />
{this.state.contextMenu === relation.id ? (
<Boundary
captureResize={true}
captureScroll={false}
enabled
onOutsideRectEvent={(e) => this._handleClick(e, relation.id)}
>
<PopoverNavigation
style={{
top: "40px",
right: "0px",
}}
navigation={[
{
text: "Copy profile URL",
onClick: (e) =>
this._handleCopy(e, `https://slate.host/${relation.user.username}`),
},
{
text: "Remove peer",
onClick: (e) => this._handleDelete(e, relation.id),
},
]}
/>
</Boundary>
) : null}
</div>
);
return (
<UserEntry
key={relation.id}
user={relation.user}
button={button}
onClick={() => {
this.props.onAction({
type: "NAVIGATE",
value: this.props.sceneId,
scene: "PUBLIC_PROFILE",
data: relation.user,
});
}}
/>
);
})
);
// let trusted = this.props.viewer.pendingTrusted
// .filter((relation) => {
// return relation.data.verified;
// })
// .map((relation) => {
// let button = (
// <div css={STYLES_ITEM_BOX} onClick={(e) => this._handleClick(e, relation.id)}>
// <SVG.MoreHorizontal height="24px" />
// {this.state.contextMenu === relation.id ? (
// <Boundary
// captureResize={true}
// captureScroll={false}
// enabled
// onOutsideRectEvent={(e) => this._handleClick(e, relation.id)}
// >
// <PopoverNavigation
// style={{
// top: "40px",
// right: "0px",
// }}
// navigation={[
// {
// text: "Copy profile URL",
// onClick: (e) =>
// this._handleCopy(e, `https://slate.host/${relation.owner.username}`),
// },
// {
// text: "Remove peer",
// onClick: (e) => this._handleDelete(e, relation.id),
// },
// ]}
// />
// </Boundary>
// ) : null}
// </div>
// );
// return (
// <UserEntry
// key={relation.id}
// user={relation.owner}
// button={button}
// onClick={() => {
// this.props.onAction({
// type: "NAVIGATE",
// value: this.props.sceneId,
// scene: "PUBLIC_PROFILE",
// data: relation.owner,
// });
// }}
// />
// );
// });
// if (!trusted) {
// trusted = [];
// }
// trusted.push(
// ...this.props.viewer.trusted
// .filter((relation) => {
// return relation.data.verified;
// })
// .map((relation) => {
// let button = (
// <div css={STYLES_ITEM_BOX} onClick={(e) => this._handleClick(e, relation.id)}>
// <SVG.MoreHorizontal height="24px" />
// {this.state.contextMenu === relation.id ? (
// <Boundary
// captureResize={true}
// captureScroll={false}
// enabled
// onOutsideRectEvent={(e) => this._handleClick(e, relation.id)}
// >
// <PopoverNavigation
// style={{
// top: "40px",
// right: "0px",
// }}
// navigation={[
// {
// text: "Copy profile URL",
// onClick: (e) =>
// this._handleCopy(e, `https://slate.host/${relation.user.username}`),
// },
// {
// text: "Remove peer",
// onClick: (e) => this._handleDelete(e, relation.id),
// },
// ]}
// />
// </Boundary>
// ) : null}
// </div>
// );
// return (
// <UserEntry
// key={relation.id}
// user={relation.user}
// button={button}
// onClick={() => {
// this.props.onAction({
// type: "NAVIGATE",
// value: this.props.sceneId,
// scene: "PUBLIC_PROFILE",
// data: relation.user,
// });
// }}
// />
// );
// })
// );
let following = this.props.viewer.subscriptions
.filter((relation) => {
@ -475,11 +475,11 @@ export default class SceneDirectory extends React.Component {
<ScenePage>
<ScenePageHeader title="Directory" />
<TabGroup
tabs={["Requests", "Trusted", "Following", "Followers"]}
tabs={["Following", "Followers"]}
value={this.state.tab}
onChange={(value) => this.setState({ tab: value })}
/>
{this.state.tab === 0 ? (
{/* {this.state.tab === 0 ? (
requests && requests.length ? (
requests
) : (
@ -498,8 +498,8 @@ export default class SceneDirectory extends React.Component {
Trusted is for your close friends.
</EmptyState>
)
) : null}
{this.state.tab === 2 ? (
) : null} */}
{this.state.tab === 0 ? (
following && following.length ? (
following
) : (
@ -509,7 +509,7 @@ export default class SceneDirectory extends React.Component {
</EmptyState>
)
) : null}
{this.state.tab === 3 ? (
{this.state.tab === 1 ? (
followers && followers.length ? (
followers
) : (

View File

@ -21,21 +21,21 @@ const STATUS_BUTTON_MAP = {
};
export default class SceneProfile extends React.Component {
_handleTrust = async (trustStatus, trustId) => {
if (trustStatus === "untrusted" || trustStatus === "sent") {
await Actions.createTrustRelationship({
userId: this.props.data.id,
});
} else if (trustStatus === "received") {
await Actions.updateTrustRelationship({
userId: this.props.data.id,
});
} else {
await Actions.deleteTrustRelationship({
id: trustId,
});
}
};
// _handleTrust = async (trustStatus, trustId) => {
// if (trustStatus === "untrusted" || trustStatus === "sent") {
// await Actions.createTrustRelationship({
// userId: this.props.data.id,
// });
// } else if (trustStatus === "received") {
// await Actions.updateTrustRelationship({
// userId: this.props.data.id,
// });
// } else {
// await Actions.deleteTrustRelationship({
// id: trustId,
// });
// }
// };
_handleFollow = async () => {
await Actions.createSubscription({
@ -45,32 +45,32 @@ export default class SceneProfile extends React.Component {
render() {
let trustId, followStatus, relation;
let trustStatus = "untrusted";
// let trustStatus = "untrusted";
let viewer = this.props.viewer;
let trust = viewer.trusted.filter((entry) => {
return entry.target_user_id === this.props.data.id;
});
if (trust.length) {
relation = trust[0];
trustId = relation.id;
if (relation.data.verified) {
trustStatus = "trusted";
} else {
trustStatus = "sent";
}
}
let pendingTrust = viewer.pendingTrusted.filter((entry) => {
return entry.owner_user_id === this.props.data.id;
});
if (pendingTrust.length) {
relation = pendingTrust[0];
trustId = relation.id;
if (pendingTrust[0].data.verified) {
trustStatus = "trusted";
} else {
trustStatus = "received";
}
}
// let trust = viewer.trusted.filter((entry) => {
// return entry.target_user_id === this.props.data.id;
// });
// if (trust.length) {
// relation = trust[0];
// trustId = relation.id;
// if (relation.data.verified) {
// trustStatus = "trusted";
// } else {
// trustStatus = "sent";
// }
// }
// let pendingTrust = viewer.pendingTrusted.filter((entry) => {
// return entry.owner_user_id === this.props.data.id;
// });
// if (pendingTrust.length) {
// relation = pendingTrust[0];
// trustId = relation.id;
// if (pendingTrust[0].data.verified) {
// trustStatus = "trusted";
// } else {
// trustStatus = "received";
// }
// }
followStatus = !!viewer.subscriptions.filter((entry) => {
return entry.target_user_id === this.props.data.id;
}).length;
@ -78,15 +78,15 @@ export default class SceneProfile extends React.Component {
let buttons = (
<div css={STYLES_BUTTONS}>
{followStatus ? (
<ButtonSecondary style={{ marginRight: 8, minWidth: 152 }} onClick={this._handleFollow}>
<ButtonSecondary style={{ marginRight: 8 }} onClick={this._handleFollow}>
Unfollow
</ButtonSecondary>
) : (
<ButtonPrimary style={{ marginRight: 8, minWidth: 152 }} onClick={this._handleFollow}>
<ButtonPrimary style={{ marginRight: 8 }} onClick={this._handleFollow}>
Follow
</ButtonPrimary>
)}
{trustStatus === "untrusted" || trustStatus === "received" ? (
{/* {trustStatus === "untrusted" || trustStatus === "received" ? (
<ButtonPrimary
style={{ marginRight: 8, minWidth: 152 }}
onClick={() => this._handleTrust(trustStatus, trustId)}
@ -100,7 +100,7 @@ export default class SceneProfile extends React.Component {
>
{STATUS_BUTTON_MAP[trustStatus]}
</ButtonSecondary>
)}
)} */}
</div>
);
return (