Merge pull request #1900 from chrisgarrity/feature/preview-presentation

Merging this PR as is to avoid more conflicts and to get it into smoke-testing. Will address the comments in subsequent PRs
This commit is contained in:
chrisgarrity 2018-05-31 15:35:20 -04:00 committed by GitHub
commit 963a18980f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 1153 additions and 442 deletions

View file

@ -29,10 +29,12 @@
"express-http-proxy": "1.1.0",
"lodash.defaults": "4.0.1",
"newrelic": "1.25.4",
"raven": "0.10.0"
"raven": "0.10.0",
"scratch-gui": "0.1.0-prerelease.20180529181946"
},
"devDependencies": {
"ajv": "6.4.0",
"approximate-number": "2.0.0",
"async": "1.5.2",
"autoprefixer": "6.3.6",
"babel-cli": "6.26.0",
@ -95,7 +97,6 @@
"redux-thunk": "2.0.1",
"sass-lint": "1.5.1",
"sass-loader": "6.0.6",
"scratch-gui": "0.1.0-prerelease.20180522203439",
"scratchr2_translations": "git://github.com/LLK/scratchr2_translations.git#master",
"slick-carousel": "1.6.0",
"source-map-support": "0.3.2",

View file

@ -18,9 +18,11 @@ $ui-border: hsla(0, 0, 85, 1); //#D9D9D9
/* 3.0 colors */
/* Using www naming convention for now, should be consistent with gui */
$ui-green: hsla(163, 83, 40, 1); //#0fbd8c Pen Primary
$ui-coral: hsla(350, 100, 70, 1); //#FF6680 More Priamry
$ui-green: hsla(163, 83, 40, 1); // #0fbd8c Pen Primary
$ui-coral: hsla(350, 100, 70, 1); // #FF6680 More Primary
$ui-coral-dark: hsla(350, 100, 60, 1); // #FF3355 More tertiary
$ui-blue-10percent: hsla(215, 100, 65, .1);
$ui-blue-25percent: hsla(215, 100, 65, .25);
$ui-orange-25percent: hsla(35, 90, 55, .25);
/* Overlay UI Gray Colors */

View file

@ -3,16 +3,18 @@
.inplace-input {
transition: all .5s ease;
border: 2px dashed $ui-dark-gray;
border-radius: 5px;
border: 2px dashed $ui-blue-25percent;
border-radius: 8px;
background-color: transparent;
padding: 0 1rem;
width: calc(100% - 2.25rem);
color: $type-gray;
&:focus {
transition: all .5s ease;
outline: none;
border: 1px solid $ui-blue;
border: 2px solid $ui-blue;
box-shadow: 0 0 0 4px $ui-blue-25percent;
}
&.fail {
@ -27,31 +29,41 @@
&::-ms-reveal, &::-ms-clear {
display: none;
}
&::placeholder {
font-style: italic;
}
}
.inplace-textarea {
transition: all 1s ease;
margin-bottom: .75rem;
border: 2px dashed $ui-dark-gray;
border-radius: 5px;
border: 2px dashed $ui-blue-25percent;
border-radius: 8px;
background-color: $ui-light-gray;
padding: .75rem 1rem;
width: calc(100% - 2.25rem);
min-height: 20rem;
width: 100%;
line-height: 1.75em;
color: $type-gray;
font-size: .875rem;
font-size: 1rem;
box-sizing: border-box;
resize: none;
&:focus {
transition: all 1s ease;
outline: none;
border: 1px solid $ui-blue;
border: 2px solid $ui-blue;
box-shadow: 0 0 0 4px $ui-blue-25percent;
}
&.fail {
border: 1px solid $ui-orange;
}
&::placeholder {
padding-top: 1rem;
text-align: center;
font-style: italic;
}
}

View file

@ -22,4 +22,8 @@
&.fail {
border: 1px solid $ui-orange;
}
&::placeholder {
font-style: italic;
}
}

View file

@ -0,0 +1,186 @@
const bindAll = require('lodash.bindall');
const PropTypes = require('prop-types');
const React = require('react');
const FormattedMessage = require('react-intl').FormattedMessage;
const injectIntl = require('react-intl').injectIntl;
const intlShape = require('react-intl').intlShape;
const Modal = require('../base/modal.jsx');
const log = require('../../../lib/log.js');
const Form = require('../../forms/form.jsx');
const Button = require('../../forms/button.jsx');
const Select = require('../../forms/select.jsx');
const Spinner = require('../../spinner/spinner.jsx');
const TextArea = require('../../forms/textarea.jsx');
require('../../forms/button.scss');
require('./modal.scss');
class ReportModal extends React.Component {
constructor (props) {
super(props);
bindAll(this, [
'handleReasonSelect',
'handleSubmit'
]);
this.state = {
prompt: props.intl.formatMessage({id: 'report.promptPlaceholder'}),
reason: '',
waiting: false
};
}
handleReasonSelect (name, value) {
const prompts = [
this.props.intl.formatMessage({id: 'report.promptCopy'}),
this.props.intl.formatMessage({id: 'report.promptUncredited'}),
this.props.intl.formatMessage({id: 'report.promptScary'}),
this.props.intl.formatMessage({id: 'report.promptLanguage'}),
this.props.intl.formatMessage({id: 'report.promptMusic'}),
this.props.intl.formatMessage({id: 'report.promptPersonal'}),
this.props.intl.formatMessage({id: 'report.promptGuidelines'}),
'not used',
this.props.intl.formatMessage({id: 'report.promptImage'})
];
this.setState({prompt: prompts[value], reason: value});
}
handleSubmit (formData) {
this.setState({waiting: true});
this.props.onReport(formData, err => {
if (err) log.error(err);
this.setState({
prompt: this.props.intl.formatMessage({id: 'report.promptPlaceholder'}),
reason: '',
waiting: false
});
});
}
render () {
const {
intl,
onReport, // eslint-disable-line no-unused-vars
type,
...modalProps
} = this.props;
const contentLabel = intl.formatMessage({id: `report.${type}`});
return (
<Modal
className="mod-report"
contentLabel={contentLabel}
{...modalProps}
>
<div>
<div className="report-modal-header">
<div className="report-content-label">
{contentLabel}
</div>
</div>
<div className="report-modal-content">
<FormattedMessage
id={`report.${type}Instructions`}
values={{
CommunityGuidelinesLink: (
<a href="/community_guidelines">
<FormattedMessage id="report.CommunityGuidelinesLinkText" />
</a>
)
}}
/>
<Form
className="report"
onSubmit={this.handleSubmit}
>
<Select
required
name="reason"
options={[
{
value: '',
label: this.props.intl.formatMessage({id: 'report.reasonPlaceHolder'})
},
{
value: '0',
label: this.props.intl.formatMessage({id: 'report.reasonCopy'})
},
{
value: '1',
label: this.props.intl.formatMessage({id: 'report.reasonUncredited'})
},
{
value: '2',
label: this.props.intl.formatMessage({id: 'report.reasonScary'})
},
{
value: '3',
label: this.props.intl.formatMessage({id: 'report.reasonLanguage'})
},
{
value: '4',
label: this.props.intl.formatMessage({id: 'report.reasonMusic'})
},
{
value: '8',
label: this.props.intl.formatMessage({id: 'report.reasonImage'})
},
{
value: '5',
label: this.props.intl.formatMessage({id: 'report.reasonPersonal'})
},
{
value: '6',
label: this.props.intl.formatMessage({id: 'general.other'})
}
]}
value={this.state.reason}
onChange={this.handleReasonSelect}
/>
<TextArea
required
className="report-text"
name="reportText"
placeholder={this.state.prompt}
validationErrors={{
maxLength: this.props.intl.formatMessage({id: 'report.tooLongError'}),
minLength: this.props.intl.formatMessage({id: 'report.tooShortError'})
}}
validations={{
// TODO find out max and min characters
maxLength: 500,
minLength: 30
}}
/>
{this.state.reportWaiting ? [
<Button
className="submit-button white"
disabled="disabled"
key="submitButton"
type="submit"
>
<Spinner />
</Button>
] : [
<Button
className="submit-button white"
key="submitButton"
type="submit"
>
<FormattedMessage id="report.send" />
</Button>
]}
</Form>
</div>
</div>
</Modal>
);
}
}
ReportModal.propTypes = {
intl: intlShape,
onReport: PropTypes.func,
onRequestClose: PropTypes.func,
type: PropTypes.string
};
module.exports = injectIntl(ReportModal);

View file

@ -0,0 +1,39 @@
@import "../../../colors";
@import "../../../frameless";
.mod-report * {
box-sizing: border-box;
}
.mod-report {
margin: 100px auto;
outline: none;
padding: 0;
width: 30rem;
overflow: hidden;
user-select: none;
}
.report-modal-header {
box-shadow: inset 0 -1px 0 0 $ui-coral-dark;
background-color: $ui-coral;
padding-top: .75rem;
width: 100%;
height: 3rem;
box-sizing: border-box;
}
.report-content-label {
text-align: center;
color: $type-white;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 1rem;
font-weight: bold;
}
.report-modal-content {
margin: 1rem auto;
width: 80%;
line-height: 1.5rem;
font-size: .875rem;
}

View file

@ -159,5 +159,28 @@
"registration.welcomeStepPrompt": "To get started, click on the button below.",
"registration.welcomeStepTitle": "Hurray! Welcome to Scratch!",
"thumbnail.by": "by"
"thumbnail.by": "by",
"report.project": "Report Project",
"report.projectInstructions": "From the dropdown below, please select the reason why you feel this project is disrespectful or inappropriate or otherwise breaks the {CommunityGuidelinesLink}.",
"report.CommunityGuidelinesLinkText": "Scratch Community Guidelines",
"report.reasonPlaceHolder": "Select a reason",
"report.reasonCopy": "Exact Copy of Project",
"report.reasonUncredited": "Uses Image/Music Without Credit",
"report.reasonScary": "Too Violent or Scary",
"report.reasonLanguage": "Inappropriate Language",
"report.reasonMusic": "Inappropriate Music",
"report.reasonImage": "Inappropriate Images",
"report.reasonPersonal": "Sharing Personal Contact Information",
"report.promptPlaceholder": "Select a reason why above.",
"report.promptCopy": "Please provide a link to the original project",
"report.promptUncredited": "Please provide links to the uncredited content",
"report.promptScary": "Please say why the project is too violent or scary",
"report.promptLanguage": "Please say where the inappropriate language occurs in the project (For example: Notes & Credits, sprite name, project text, etc.)",
"report.promptMusic": "Please say the name of the audio file with the inappropriate music",
"report.promptPersonal": "Please say where the personal contact information is shared (For example: Notes & Credits, sprite name, project text, etc.)",
"report.promptGuidelines": "Please be specific about why this project does not follow our Community Guidelines",
"report.promptImage": "Please say the name of the sprite or the backdrop with the inappropriate image",
"report.tooLongError": "That's too long! Please find a way to shorten your text.",
"report.tooShortError": "That's too short. Please describe in detail what's inappropriate or disrespectful about the project.",
"report.send": "Send"
}

View file

@ -13,19 +13,21 @@ module.exports.Status = keyMirror({
module.exports.getInitialState = () => ({
status: {
project: module.exports.Status.NOT_FETCHED,
credit: module.exports.Status.NOT_FETCHED,
comments: module.exports.Status.NOT_FETCHED,
faved: module.exports.Status.NOT_FETCHED,
loved: module.exports.Status.NOT_FETCHED,
original: module.exports.Status.NOT_FETCHED,
parent: module.exports.Status.NOT_FETCHED,
remixes: module.exports.Status.NOT_FETCHED,
studios: module.exports.Status.NOT_FETCHED
},
projectInfo: {},
remixes: [],
credit: {},
comments: [],
faved: false,
loved: false,
original: {},
parent: {},
studios: []
});
@ -43,14 +45,18 @@ module.exports.previewReducer = (state, action) => {
return Object.assign({}, state, {
remixes: action.items
});
case 'SET_ORIGINAL':
return Object.assign({}, state, {
original: action.info
});
case 'SET_PARENT':
return Object.assign({}, state, {
parent: action.info
});
case 'SET_STUDIOS':
return Object.assign({}, state, {
studios: action.items
});
case 'SET_CREDIT':
return Object.assign({}, state, {
credit: action.info
});
case 'SET_COMMENTS':
return Object.assign({}, state, {
comments: action.items
@ -85,8 +91,13 @@ module.exports.setProjectInfo = info => ({
info: info
});
module.exports.setCreditInfo = info => ({
type: 'SET_CREDIT',
module.exports.setOriginalInfo = info => ({
type: 'SET_ORIGINAL',
info: info
});
module.exports.setParentInfo = info => ({
type: 'SET_PARENT',
info: info
});
@ -140,23 +151,43 @@ module.exports.getProjectInfo = (id, token) => (dispatch => {
});
});
module.exports.getCreditInfo = id => (dispatch => {
dispatch(module.exports.setFetchStatus('credit', module.exports.Status.FETCHING));
module.exports.getOriginalInfo = id => (dispatch => {
dispatch(module.exports.setFetchStatus('original', module.exports.Status.FETCHING));
api({
uri: `/projects/${id}`
}, (err, body) => {
if (err) {
dispatch(module.exports.setFetchStatus('credit', module.exports.Status.ERROR));
dispatch(module.exports.setFetchStatus('original', module.exports.Status.ERROR));
dispatch(module.exports.setError(err));
return;
}
if (typeof body === 'undefined') {
dispatch(module.exports.setFetchStatus('credit', module.exports.Status.ERROR));
dispatch(module.exports.setError('No credit info'));
dispatch(module.exports.setFetchStatus('original', module.exports.Status.ERROR));
dispatch(module.exports.setError('No original info'));
return;
}
dispatch(module.exports.setFetchStatus('credit', module.exports.Status.FETCHED));
dispatch(module.exports.setCreditInfo(body));
dispatch(module.exports.setFetchStatus('original', module.exports.Status.FETCHED));
dispatch(module.exports.setOriginalInfo(body));
});
});
module.exports.getParentInfo = id => (dispatch => {
dispatch(module.exports.setFetchStatus('parent', module.exports.Status.FETCHING));
api({
uri: `/projects/${id}`
}, (err, body) => {
if (err) {
dispatch(module.exports.setFetchStatus('parent', module.exports.Status.ERROR));
dispatch(module.exports.setError(err));
return;
}
if (typeof body === 'undefined') {
dispatch(module.exports.setFetchStatus('parent', module.exports.Status.ERROR));
dispatch(module.exports.setError('No parent info'));
return;
}
dispatch(module.exports.setFetchStatus('parent', module.exports.Status.FETCHED));
dispatch(module.exports.setParentInfo(body));
});
});

View file

@ -1,10 +1,11 @@
const bindAll = require('lodash.bindall');
const FormattedDate = require('react-intl').FormattedDate;
const injectIntl = require('react-intl').injectIntl;
const intlShape = require('react-intl').intlShape;
const PropTypes = require('prop-types');
const React = require('react');
const Formsy = require('formsy-react').default;
const classNames = require('classnames');
const approx = require('approximate-number');
const GUI = require('scratch-gui').default;
const IntlGUI = injectIntl(GUI);
@ -12,293 +13,393 @@ const IntlGUI = injectIntl(GUI);
const sessionActions = require('../../redux/session.js');
const decorateText = require('../../lib/decorate-text.jsx');
const FlexRow = require('../../components/flex-row/flex-row.jsx');
const Button = require('../../components/forms/button.jsx');
const Avatar = require('../../components/avatar/avatar.jsx');
const CappedNumber = require('../../components/cappednumber/cappednumber.jsx');
const ShareBanner = require('../../components/share-banner/share-banner.jsx');
const ThumbnailColumn = require('../../components/thumbnailcolumn/thumbnailcolumn.jsx');
const InplaceInput = require('../../components/forms/inplace-input.jsx');
const ReportModal = require('../../components/modal/report/modal.jsx');
const projectShape = require('./projectshape.jsx').projectShape;
require('./preview.scss');
const PreviewPresentation = props => {
const {
creditInfo,
editable,
faved,
favoriteCount,
intl,
isFullScreen,
loved,
loveCount,
projectId,
projectInfo,
remixes,
sessionStatus,
studios,
user,
onFavoriteClicked,
onLoveClicked,
onSeeInside,
onUpdate
// ...otherProps TBD
} = props;
const shareDate = (projectInfo.history && projectInfo.history.shared) ? projectInfo.history.shared : '';
return (
<div className="preview">
<ShareBanner>
<FlexRow className="preview-row">
<span className="share-text">
This project is not shared so only you can see it. Click share to let everyone see it!
</span>
<button className="button share-button">
Share
</button>
</FlexRow>
</ShareBanner>
{ projectInfo && projectInfo.author && projectInfo.author.id && (
<div className="inner">
<Formsy>
class PreviewPresentation extends React.Component {
constructor (props) {
super(props);
bindAll(this, [
'handleReportClick',
'handleReportClose',
'handleReportSubmit'
]);
this.state = {
reportOpen: false
};
}
handleReportClick (e) {
e.preventDefault();
this.setState({reportOpen: true});
}
handleReportClose () {
this.setState({reportOpen: false});
}
handleReportSubmit (formData, callback) {
const data = {
...formData,
id: this.props.projectId,
username: this.props.user.username
};
console.log('submit report data', data); // eslint-disable-line no-console
// TODO: pass error to modal via callback.
callback();
this.setState({reportOpen: false});
}
render () {
const {
editable,
faved,
favoriteCount,
isFullScreen,
loved,
loveCount,
originalInfo,
parentInfo,
projectId,
projectInfo,
remixes,
sessionStatus,
studios,
user,
onFavoriteClicked,
onLoveClicked,
onSeeInside,
onUpdate
// ...otherProps TBD
} = this.props;
const shareDate = (projectInfo.history && projectInfo.history.shared) ? projectInfo.history.shared : '';
return (
<div className="preview">
{projectInfo.history && shareDate === '' &&
<ShareBanner>
<FlexRow className="preview-row">
<FlexRow className="project-header">
<Avatar
src={`https://cdn2.scratch.mit.edu/get_image/user/${projectInfo. author.id}_48x48.png`}
/>
<div className="title">
{editable ?
<InplaceInput
className="project-title"
handleUpdate={onUpdate}
name="title"
validationErrors={{
maxLength: 'Sorry title is too long'
// maxLength: props.intl.formatMessage({
// id: 'project.titleMaxLength'
// })
}}
validations={{
// TODO: actual 100
maxLength: 40
}}
value={projectInfo.title}
/> :
<div className="project-title">{projectInfo.title}</div>
}
{`${intl.formatMessage({id: 'thumbnail.by'})} `}
<span className="share-text">
This project is not shared so only you can see it. Click share to let everyone see it!
</span>
<Button className="button share-button">
Share
</Button>
</FlexRow>
</ShareBanner>
}
{ projectInfo && projectInfo.author && projectInfo.author.id && (
<div className="inner">
<Formsy>
<FlexRow className="preview-row">
<FlexRow className="project-header">
<a href={`/users/${projectInfo.author.username}`}>
{projectInfo.author.username}
<Avatar
alt={projectInfo.author.username}
src={`https://cdn2.scratch.mit.edu/get_image/user/${projectInfo. author.id}_48x48.png`}
/>
</a>
<div className="title">
{editable ?
<InplaceInput
className="project-title"
handleUpdate={onUpdate}
name="title"
validationErrors={{
maxLength: 'Sorry title is too long'
// maxLength: props.intl.formatMessage({
// id: 'project.titleMaxLength'
// })
}}
validations={{
maxLength: 100
}}
value={projectInfo.title}
/> :
<div className="project-title">{projectInfo.title}</div>
}
</div>
</FlexRow>
<div className="project-buttons">
{sessionStatus === sessionActions.Status.FETCHED &&
Object.keys(user).length > 0 &&
user.id !== projectInfo.author.id &&
<Button className="button remix-button">
Remix
</Button>
}
<Button
className="button see-inside-button"
onClick={onSeeInside}
>
See Inside
</Button>
</div>
</FlexRow>
<div className="project-buttons">
{sessionStatus === sessionActions.Status.FETCHED &&
Object.keys(user).length > 0 &&
user.id !== projectInfo.author.id &&
<button className="button remix-button">
Remix
</button>
}
<button
className="button see-inside-button"
onClick={onSeeInside}
>
See Inside
</button>
</div>
</FlexRow>
<FlexRow className="preview-row">
<IntlGUI
isPlayerOnly
basePath="/"
className="guiPlayer"
isFullScreen={isFullScreen}
previewInfoVisible="false"
projectId={projectId}
/>
<FlexRow className="project-notes">
{shareDate && (
<FlexRow className="preview-row">
<div className="guiPlayer">
<IntlGUI
isPlayerOnly
basePath="/"
className="guiPlayer"
isFullScreen={isFullScreen}
previewInfoVisible="false"
projectId={projectId}
/>
</div>
<FlexRow className="project-notes">
{parentInfo && parentInfo.author && parentInfo.id && (
<FlexRow className="remix-credit">
<Avatar
className="remix"
src={`https://cdn2.scratch.mit.edu/get_image/user/${parentInfo.author.id}_48x48.png`}
/>
<div className="credit-text">
Thanks to <a
href={`/users/${parentInfo.author.username}`}
>
{parentInfo.author.username}
</a> for the original project <a
href={`/preview/${parentInfo.id}`}
>
{parentInfo.title}
</a>.
</div>
</FlexRow>
)}
{originalInfo && originalInfo.author && originalInfo.id && (
<FlexRow className="remix-credit">
<Avatar
className="remix"
src={`https://cdn2.scratch.mit.edu/get_image/user/${originalInfo.author.id}_48x48.png`}
/>
<div className="credit-text">
Thanks to <a
href={`/users/${originalInfo.author.username}`}
>
{originalInfo.author.username}
</a> for the original project <a
href={`/preview/${originalInfo.id}`}
>
{originalInfo.title}
</a>.
</div>
</FlexRow>
)}
{/* eslint-disable max-len */}
<FlexRow className="description-block">
<div className="project-textlabel">
Instructions
</div>
{editable ?
<InplaceInput
className={classNames(
'project-description-edit',
{remixes: parentInfo && parentInfo.author}
)}
handleUpdate={onUpdate}
name="instructions"
placeholder="Tell people how to use your project (such as which keys to press)."
type="textarea"
validationErrors={{
maxLength: 'Sorry description is too long'
// maxLength: props.intl.formatMessage({
// id: 'project.descriptionMaxLength'
// })
}}
validations={{
// TODO: actual 5000
maxLength: 1000
}}
value={projectInfo.instructions}
/> :
<div className="project-description">
{decorateText(projectInfo.instructions)}
</div>
}
</FlexRow>
<FlexRow className="description-block">
<div className="project-textlabel">
Notes and Credits
</div>
{editable ?
<InplaceInput
className={classNames(
'project-description-edit',
'last',
{remixes: parentInfo && parentInfo.author}
)}
handleUpdate={onUpdate}
name="description"
placeholder="How did you make this project? Did you use ideas scripts or artwork from other people? Thank them here."
type="textarea"
validationErrors={{
maxLength: 'Sorry description is too long'
// maxLength: props.intl.formatMessage({
// id: 'project.descriptionMaxLength'
// })
}}
validations={{
// TODO: actual 5000
maxLength: 1000
}}
value={projectInfo.description}
/> :
<div className="project-description last">
{decorateText(projectInfo.description)}
</div>
}
</FlexRow>
{/* eslint-enable max-len */}
</FlexRow>
</FlexRow>
<FlexRow className="preview-row">
<FlexRow className="stats">
<div
className={classNames('project-loves', {loved: loved})}
key="loves"
onClick={onLoveClicked}
>
{approx(loveCount, {decimal: false})}
</div>
<div
className={classNames('project-favorites', {favorited: faved})}
key="favorites"
onClick={onFavoriteClicked}
>
{approx(favoriteCount, {decimal: false})}
</div>
<div
className="project-remixes"
key="remixes"
>
{approx(projectInfo.stats.remixes, {decimal: false})}
</div>
<div
className="project-views"
key="views"
>
<CappedNumber value={projectInfo.stats.views} />
</div>
</FlexRow>
<FlexRow className="subactions">
<div className="share-date">
<div className="copyleft">&copy;</div>
{' '}
{/* eslint-disable react/jsx-sort-props */}
<FormattedDate
value={Date.parse(shareDate)}
day="2-digit"
month="short"
year="numeric"
/>
{shareDate === null ?
'Unshared' :
<FormattedDate
value={Date.parse(shareDate)}
day="2-digit"
month="short"
year="numeric"
/>
}
{/* eslint-enable react/jsx-sort-props */}
</div>
)}
{creditInfo && creditInfo.author && creditInfo.id && (
<FlexRow className="remix-credit">
<Avatar
className="remix"
src={`https://cdn2.scratch.mit.edu/get_image/user/${creditInfo.author.id}_48x48.png`}
/>
<div className="credit-text">
Thanks to <a
href={`/users/${creditInfo.author.username}`}
>
{creditInfo.author.username}
</a> for the original project <a
href={`/preview/${creditInfo.id}`}
>
{creditInfo.title}
</a>.
</div>
<FlexRow className="action-buttons">
<Button className="action-button studio-button">
Add to Studio
</Button>
<Button className="action-button copy-link-button">
Copy Link
</Button>
{
sessionStatus === sessionActions.Status.FETCHED &&
Object.keys(user).length > 0 &&
user.id !== projectInfo.author.id && [
<Button
className="action-button report-button"
key="report-button"
onClick={this.handleReportClick}
>
Report
</Button>,
<ReportModal
isOpen={this.state.reportOpen}
key="report-modal"
type="project"
onReport={this.handleReportSubmit}
onRequestClose={this.handleReportClose}
/>
]
}
</FlexRow>
)
}
{editable ?
<InplaceInput
className="project-description"
handleUpdate={onUpdate}
name="description"
type="textarea"
validationErrors={{
maxLength: 'Sorry description is too long'
// maxLength: props.intl.formatMessage({
// id: 'project.descriptionMaxLength'
// })
}}
validations={{
// TODO: actual 5000
maxLength: 1000
}}
value={projectInfo.description}
/> :
<div className="project-description">
{decorateText(projectInfo.description)}
</div>
}
</FlexRow>
</FlexRow>
<FlexRow className="preview-row">
<FlexRow className="stats">
<div
className={classNames('project-loves', {loved: loved})}
key="loves"
onClick={onLoveClicked}
>
{loveCount}
</div>
<div
className={classNames('project-favorites', {favorited: faved})}
key="favorites"
onClick={onFavoriteClicked}
>
{favoriteCount}
</div>
<div
className="project-remixes"
key="remixes"
>
{projectInfo.remix.count}
</div>
<div
className="project-views"
key="views"
>
<CappedNumber value={projectInfo.stats.views} />
</div>
</FlexRow>
<FlexRow className="action-buttons">
<a href="#">
<li>
Add to Studio
</li>
</a>
<a href="#">
<li>
Social
</li>
</a>
<a href="#">
<li className="report">
Report
</li>
</a>
</FlexRow>
</FlexRow>
<FlexRow className="preview-row">
<div className="comments-container">
<div className="project-title">
Comments go here
</div>
</div>
<FlexRow className="column">
<FlexRow className="remix-list">
<div className="project-title">
Remixes
</div>
{remixes && remixes.length === 0 ? (
<span>No remixes</span>
) : (
<ThumbnailColumn
cards
showAvatar
itemType="preview"
items={remixes.slice(0, 5)}
showFavorites={false}
showLoves={false}
showViews={false}
/>
)}
</FlexRow>
<FlexRow className="studio-list">
</FlexRow>
<FlexRow className="preview-row">
<div className="comments-container">
<div className="project-title">
Studios
Comments go here
</div>
{studios && studios.length === 0 ? (
<span>No studios</span>
) : (
<ThumbnailColumn
cards
showAvatar
itemType="gallery"
items={studios.slice(0, 5)}
showFavorites={false}
showLoves={false}
showViews={false}
/>
</div>
<FlexRow className="column">
{/* hide remixes if there aren't any */}
{remixes && remixes.length !== 0 && (
<FlexRow className="remix-list">
<div className="project-title">
Remixes
</div>
{remixes && remixes.length === 0 ? (
// TODO: style remix invitation
<span>Invite user to remix</span>
) : (
<ThumbnailColumn
cards
showAvatar
itemType="preview"
items={remixes.slice(0, 5)}
showFavorites={false}
showLoves={false}
showViews={false}
/>
)}
</FlexRow>
)}
{/* hide studios if there aren't any */}
{studios && studios.length !== 0 && (
<FlexRow className="studio-list">
<div className="project-title">
Studios
</div>
{studios && studios.length === 0 ? (
// TODO: invite user to add to studio?
<span>None </span>
) : (
<ThumbnailColumn
cards
showAvatar
itemType="gallery"
items={studios.slice(0, 5)}
showFavorites={false}
showLoves={false}
showViews={false}
/>
)}
</FlexRow>
)}
</FlexRow>
</FlexRow>
</FlexRow>
</Formsy>
</div>
)}
</div>
);
};
</Formsy>
</div>
)}
</div>
);
}
}
PreviewPresentation.propTypes = {
creditInfo: PropTypes.shape({
id: PropTypes.number,
title: PropTypes.string,
description: PropTypes.string,
author: PropTypes.shape({id: PropTypes.number}),
history: PropTypes.shape({
created: PropTypes.string,
modified: PropTypes.string,
shared: PropTypes.string
}),
stats: PropTypes.shape({
views: PropTypes.number,
loves: PropTypes.number,
favorites: PropTypes.number
}),
remix: PropTypes.shape({
parent: PropTypes.number,
root: PropTypes.number
})
}),
editable: PropTypes.bool,
faved: PropTypes.bool,
favoriteCount: PropTypes.number,
intl: intlShape,
isFullScreen: PropTypes.bool,
loveCount: PropTypes.number,
loved: PropTypes.bool,
@ -306,27 +407,10 @@ PreviewPresentation.propTypes = {
onLoveClicked: PropTypes.func,
onSeeInside: PropTypes.func,
onUpdate: PropTypes.func,
originalInfo: projectShape,
parentInfo: projectShape,
projectId: PropTypes.string,
projectInfo: PropTypes.shape({
id: PropTypes.number,
title: PropTypes.string,
description: PropTypes.string,
author: PropTypes.shape({id: PropTypes.number}),
history: PropTypes.shape({
created: PropTypes.string,
modified: PropTypes.string,
shared: PropTypes.string
}),
stats: PropTypes.shape({
views: PropTypes.number,
loves: PropTypes.number,
favorites: PropTypes.number
}),
remix: PropTypes.shape({
parent: PropTypes.number,
root: PropTypes.number
})
}),
projectInfo: projectShape,
remixes: PropTypes.arrayOf(PropTypes.object),
sessionStatus: PropTypes.string.isRequired,
studios: PropTypes.arrayOf(PropTypes.object),

View file

@ -7,6 +7,7 @@ const Page = require('../../components/page/www/page.jsx');
const render = require('../../lib/render.jsx');
const PreviewPresentation = require('./presentation.jsx');
const projectShape = require('./projectshape.jsx').projectShape;
const sessionActions = require('../../redux/session.js');
const previewActions = require('../../redux/preview.js');
@ -53,8 +54,13 @@ class Preview extends React.Component {
if (this.props.projectInfo.id !== prevProps.projectInfo.id) {
this.initCounts(this.props.projectInfo.stats.favorites, this.props.projectInfo.stats.loves);
this.handlePermissions();
if (this.props.projectInfo.remix.root !== null) {
this.props.getCreditInfo(this.props.projectInfo.remix.root);
if (this.props.projectInfo.remix.parent !== null) {
this.props.getParentInfo(this.props.projectInfo.remix.parent);
}
if (this.props.projectInfo.remix.root !== null &&
this.props.projectInfo.remix.root !== this.props.projectInfo.remix.parent
) {
this.props.getOriginalInfo(this.props.projectInfo.remix.root);
}
}
if (this.props.playerMode !== prevProps.playerMode || this.props.fullScreen !== prevProps.fullScreen) {
@ -64,6 +70,19 @@ class Preview extends React.Component {
componentWillUnmount () {
this.removeEventListeners();
}
initState () {
const pathname = window.location.pathname.toLowerCase();
const parts = pathname.split('/').filter(Boolean);
// parts[0]: 'preview'
// parts[1]: either :id or 'editor'
// parts[2]: undefined if no :id, otherwise either 'editor' or 'fullscreen'
return {
editable: false,
favoriteCount: 0,
loveCount: 0,
projectId: parts[1] === 'editor' ? 0 : parts[1]
};
}
addEventListeners () {
window.addEventListener('popstate', this.handlePopState);
}
@ -103,19 +122,6 @@ class Preview extends React.Component {
);
}
}
initState () {
const pathname = window.location.pathname.toLowerCase();
const parts = pathname.split('/').filter(Boolean);
// parts[0]: 'preview'
// parts[1]: either :id or 'editor'
// parts[2]: undefined if no :id, otherwise either 'editor' or 'fullscreen'
return {
editable: false,
favoriteCount: 0,
loveCount: 0,
projectId: parts[1] === 'editor' ? 0 : parts[1]
};
}
handleFavoriteToggle () {
this.props.setFavedStatus(
!this.props.faved,
@ -179,13 +185,14 @@ class Preview extends React.Component {
<Page>
<PreviewPresentation
comments={this.props.comments}
creditInfo={this.props.credit}
editable={this.state.editable}
faved={this.props.faved}
favoriteCount={this.state.favoriteCount}
isFullScreen={this.state.isFullScreen}
loveCount={this.state.loveCount}
loved={this.props.loved}
originalInfo={this.props.original}
parentInfo={this.props.parent}
projectId={this.state.projectId}
projectInfo={this.props.projectInfo}
remixes={this.props.remixes}
@ -210,61 +217,20 @@ class Preview extends React.Component {
Preview.propTypes = {
comments: PropTypes.arrayOf(PropTypes.object),
credit: PropTypes.shape({
id: PropTypes.number,
title: PropTypes.string,
description: PropTypes.string,
author: PropTypes.shape({
id: PropTypes.number
}),
history: PropTypes.shape({
created: PropTypes.string,
modified: PropTypes.string,
shared: PropTypes.string
}),
stats: PropTypes.shape({
views: PropTypes.number,
loves: PropTypes.number,
favorites: PropTypes.number
}),
remix: PropTypes.shape({
parent: PropTypes.number,
root: PropTypes.number
})
}),
faved: PropTypes.bool,
fullScreen: PropTypes.bool,
getCreditInfo: PropTypes.func.isRequired,
getFavedStatus: PropTypes.func.isRequired,
getLovedStatus: PropTypes.func.isRequired,
getOriginalInfo: PropTypes.func.isRequired,
getParentInfo: PropTypes.func.isRequired,
getProjectInfo: PropTypes.func.isRequired,
getRemixes: PropTypes.func.isRequired,
getStudios: PropTypes.func.isRequired,
loved: PropTypes.bool,
original: projectShape,
parent: projectShape,
playerMode: PropTypes.bool,
projectInfo: PropTypes.shape({
author: PropTypes.shape({
id: PropTypes.number,
username: PropTypes.string
}),
description: PropTypes.string,
history: PropTypes.shape({
created: PropTypes.string,
modified: PropTypes.string,
shared: PropTypes.string
}),
id: PropTypes.number,
remix: PropTypes.shape({
parent: PropTypes.number,
root: PropTypes.number
}),
stats: PropTypes.shape({
views: PropTypes.number,
loves: PropTypes.number,
favorites: PropTypes.number
}),
title: PropTypes.string
}),
projectInfo: projectShape,
remixes: PropTypes.arrayOf(PropTypes.object),
sessionStatus: PropTypes.string,
setFavedStatus: PropTypes.func.isRequired,
@ -292,10 +258,11 @@ Preview.defaultProps = {
const mapStateToProps = state => ({
projectInfo: state.preview.projectInfo,
credit: state.preview.credit,
comments: state.preview.comments,
faved: state.preview.faved,
loved: state.preview.loved,
original: state.preview.original,
parent: state.preview.parent,
remixes: state.preview.remixes,
sessionStatus: state.session.status,
studios: state.preview.studios,
@ -306,8 +273,11 @@ const mapStateToProps = state => ({
const mapDispatchToProps = dispatch => ({
getCreditInfo: id => {
dispatch(previewActions.getCreditInfo(id));
getOriginalInfo: id => {
dispatch(previewActions.getOriginalInfo(id));
},
getParentInfo: id => {
dispatch(previewActions.getParentInfo(id));
},
getProjectInfo: (id, token) => {
dispatch(previewActions.getProjectInfo(id, token));
@ -333,8 +303,11 @@ const mapDispatchToProps = dispatch => ({
refreshSession: () => {
dispatch(sessionActions.refreshSession());
},
setCreditInfo: info => {
dispatch(previewActions.setCreditInfo(info));
setOriginalInfo: info => {
dispatch(previewActions.setOriginalInfo(info));
},
setParentInfo: info => {
dispatch(previewActions.setParentInfo(info));
},
updateProject: (id, formData, username, token) => {
dispatch(previewActions.updateProject(id, formData, username, token));

View file

@ -1,6 +1,22 @@
@import "../../colors";
@import "../../frameless";
/* stage size contants
* this is a hack right now - stage includes padding of .5rem (8px) for alignment in gui
* in www the player is placed with margin -.5rem to align the edge.
* the height is calculated from the actual height on the page (404)
*/
$gui-width: 496px;
$stage-width: 480px;
$stage-height: 404px;
// remix credit height: 52px
// project text label line-height + margin-bottom .5rem: 19px + 8px = 27px
// Formsy wrapper adds 3px to the input height for
$description-input: 166px; // $stage-height / 2 - $project-label - $wrapper - margin
$description-input-small: 120px; // normal $description-input - $remix-credit
/* override view padding for share banner */
#view {
padding: 0 0 20px 0;
@ -15,8 +31,6 @@
height: 100%;
}
// .gui * { box-sizing: border-box; }
.preview {
.project-title {
@ -31,16 +45,29 @@
}
}
.project-header {
margin-right: 2rem;
flex-grow: 1;
justify-content: flex-start;
align-items: flex-start;
.inplace-input {
height: calc(3rem - 4px);
}
}
img {
&.avatar {
border: 0;
border-radius: 5px;
width: 3rem;
height: 3rem;
&.remix {
margin-right: .5em;
width: 1.5rem;
width: 2rem;
height: 2rem;
}
}
}
@ -49,6 +76,7 @@
margin-left: 1rem;
text-align: left;
font-size: .8rem;
flex-grow: 1;
}
.validation-message {
@ -113,6 +141,7 @@
.share-button,
.remix-button,
.see-inside-button {
margin-top: 0;
font-size: .875rem;
font-weight: normal;
@ -122,8 +151,8 @@
background-repeat: no-repeat;
background-position: center center;
background-size: contain;
width: 1.5rem;
height: 1.5rem;
width: 1.25rem;
height: 1.25rem;
vertical-align: middle;
content: "";
}
@ -137,7 +166,7 @@
background-color: $ui-orange;
&:before {
background-image: url("/svgs/favorite/favorite_type-gray.svg");
background-image: url("/svgs/project/share-white.svg");
}
}
@ -145,14 +174,14 @@
background-color: $ui-green;
&:before {
background-image: url("/svgs/remix/remix_type-gray.svg");
background-image: url("/svgs/project/remix-white.svg");
}
}
.see-inside-button {
&:before {
background-image: url("/images/emoji/cool-cat.png");
background-image: url("/svgs/project/see-inside-white.svg");
}
}
@ -164,19 +193,31 @@
.guiPlayer {
display: inline-block;
width: 480px;
margin-left: -.5rem;
width: $gui-width;
}
.project-notes {
width: 45%;
height: 404px;
// not 1.5rem because of stage padding
margin-left: 1rem;
height: $stage-height;
align-items: flex-start;
flex: 1;
flex-flow: column;
align-items: left;
}
.share-date {
height: 2.5rem;
margin-right: .75rem;
vertical-align: middle;
line-height: 2rem;
color: $type-gray;
font-size: .875rem;
}
.subactions {
margin-left: 1.5rem;
justify-content: flex-end;
flex: 1;
}
.remix-credit {
@ -185,7 +226,7 @@
border-radius: 8px;
background-color: $ui-blue-10percent;
padding: .5rem;
width: 100%;
width: calc(100% - 1rem);
flex-wrap: nowrap;
align-items: flex-start;
}
@ -194,22 +235,56 @@
font-size: .875rem;
flex-shrink: 1;
}
.description-block {
width: 100%;
flex-direction: column;
align-items: flex-start;
flex-grow: 1;
}
.project-textlabel {
margin: 0 0 .5rem 0;
font-size: 1rem;
font-weight: bold;
}
.project-description {
margin-bottom: .75rem;
border: 1px solid $ui-blue-10percent;
border-radius: 8px;
background-color: $ui-blue-10percent;
padding: .5rem;
width: calc(100% - (1rem + 2px));
white-space: pre-line;
font-size: 1rem;
// flex-grow
flex: 1;
}
.project-description.last {
margin-bottom: 0;
}
.project-description-edit {
margin-bottom: .75rem;
border: 1px solid $ui-blue-10percent;
border-radius: 8px;
background-color: $ui-blue-10percent;
padding: .5rem;
width: 100%;
white-space: pre-line;
overflow-y: scroll;
// flex-grow
flex: 1;
&.last {
margin-bottom: 0;
}
&.textarea-row {
border: 0;
background-color: inherit;
padding: 0;
overflow: visible;
}
&.has-error {
@ -217,6 +292,14 @@
transform: translate(26rem, 0);
}
}
.inplace-textarea {
height: $description-input;
}
}
.project-description-edit.remixes .inplace-textarea {
height: $description-input-small;
}
.copyleft {
@ -227,7 +310,7 @@
}
.stats {
width: 480px;
line-height: 2rem;
justify-content: flex-start;
}
@ -238,17 +321,18 @@
display: inline;
padding-right: 2rem;
font-size: 1.25rem;
font-size: 1rem;
font-weight: bold;
&:before {
display: inline-block;
margin-right: .1rem;
margin-right: .5rem;
background-repeat: no-repeat;
background-position: center center;
background-size: contain;
width: 1.5rem;
height: 1.5rem;
vertical-align: text-bottom;
vertical-align: -.25rem;
content: "";
}
}
@ -258,14 +342,16 @@
cursor: pointer;
&:before {
background-image: url("/svgs/love/love_type-gray.svg");
opacity: .5;
background-image: url("/svgs/project/love-gray.svg");
}
}
.project-loves.loved {
&:before {
background-image: url("/svgs/messages/love.svg");
opacity: 1;
background-image: url("/svgs/project/love-red.svg");
}
}
@ -274,85 +360,122 @@
cursor: pointer;
&:before {
background-image: url("/svgs/favorite/favorite_type-gray.svg");
opacity: .5;
background-image: url("/svgs/project/fav-gray.svg");
}
}
.project-favorites.favorited {
&:before {
background-image: url("/svgs/messages/favorite.svg");
opacity: 1;
background-image: url("/svgs/project/fav-yellow.svg");
}
}
.project-remixes {
&:before {
background-image: url("/svgs/remix/remix_type-gray.svg");
opacity: .5;
background-image: url("/svgs/project/remix-gray.svg");
}
}
.project-views {
&:before {
background-image: url("/svgs/view/view_type-gray.svg");
opacity: .5;
background-image: url("/svgs/project/views-gray.svg");
}
}
.action-buttons {
display: flex;
width: 40%;
color: $type-white;
font-size: .8rem;
font-weight: 500;
justify-content: flex-end;
flex-wrap: wrap;
}
li {
.action-button {
margin: 0 0 0 .5rem;
border-radius: 19px;
background-color: $ui-blue;
padding: 0 .75rem;
height: 2rem;
text-decoration: none;
line-height: .875rem;
font-size: .75rem;
font-weight: normal;
// &:hover {
// transition: background-color .25s ease;
// border-color: transparent;
// background-color: $active-gray;
// }
//
// &:active {
// border: 0 solid transparent;
// box-shadow: inset 0 0 5px $box-shadow-gray;
// background-color: $active-dark-gray;
// padding: calc(.75em + 1px) calc(1.5em + 1px);
// }
//
// &.report {
// border: 1px solid $ui-coral;
// background-color: $ui-coral;
//
// &:hover {
// transition: background-color .25s ease;
// border-color: transparent;
// background-color: $active-gray;
// }
//
// &:active {
// border: 0 solid transparent;
// box-shadow: inset 0 0 5px $box-shadow-gray;
// background-color: $active-dark-gray;
// padding: calc(.75em + 1px) calc(1.5em + 1px);
// }
// }
}
.studio-button,
.copy-link-button,
.report-button {
&:before {
display: inline-block;
margin: 0 5px;
border: 1px solid $ui-blue;
border-radius: 50px;
background-color: $ui-blue;
padding: .5em .75em .5em 1.5em;
text-decoration: none;
color: $type-white;
list-style-type: none;
&:hover {
transition: background-color .25s ease;
border-color: transparent;
background-color: $active-gray;
}
&:active {
border: 0 solid transparent;
box-shadow: inset 0 0 5px $box-shadow-gray;
background-color: $active-dark-gray;
padding: calc(.75em + 1px) calc(1.5em + 1px);
}
&.report {
border: 1px solid $ui-coral;
background-color: $ui-coral;
&:hover {
transition: background-color .25s ease;
border-color: transparent;
background-color: $active-gray;
}
&:active {
border: 0 solid transparent;
box-shadow: inset 0 0 5px $box-shadow-gray;
background-color: $active-dark-gray;
padding: calc(.75em + 1px) calc(1.5em + 1px);
}
}
margin-right: .25rem;
background-repeat: no-repeat;
background-position: center center;
background-size: contain;
width: .875rem;
height: .875rem;
vertical-align: bottom;
content: "";
}
}
.studio-button {
&:before {
background-image: url("/svgs/project/studio-add-white.svg");
}
}
.copy-link-button {
&:before {
background-image: url("/svgs/project/copy-link-white.svg");
}
}
.report-button {
background-color: $ui-coral;
&:before {
background-image: url("/svgs/project/report-white.svg");
}
}
.remix-list,
.studio-list {
flex-direction: column;
@ -372,3 +495,8 @@
}
}
}
.report-text textarea {
// override min-height from default settings (for teacher registration)
min-height: 8rem;
}

View file

@ -0,0 +1,35 @@
const PropTypes = require('prop-types');
const {
number,
string,
shape
} = PropTypes;
export const projectShape = shape({
id: number,
instructions: string,
title: string,
description: string,
author: shape({
id: number,
username: string
}),
image: string,
history: shape({
created: string,
modified: string,
shared: string
}),
stats: shape({
views: number,
loves: number,
favorites: number,
comments: number,
remixes: number
}),
remix: shape({
parent: number,
root: number
})
});

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>copy-link-gray</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="copy-link-gray" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M5.8303376,18.0021888 C4.84870996,18.0021888 3.86840883,17.6294356 3.12024939,16.8812761 C1.62658354,15.3876103 1.62658354,12.9574186 3.12024939,11.4637527 L5.93380646,8.65019566 C6.32247795,8.26152418 6.95257677,8.26152418 7.34124826,8.65019566 C7.72991975,9.03886715 7.72991975,9.66896597 7.34124826,10.0576375 L4.52769119,12.8711945 C3.81004179,13.5888439 3.81004179,14.7575114 4.52769119,15.4751608 C5.24401406,16.1914837 6.41268157,16.1941368 7.13165749,15.4751608 L9.94521457,12.6629303 C10.3338861,12.2742588 10.9626584,12.2742588 11.3513298,12.6629303 C11.7400013,13.0516018 11.7400013,13.6803741 11.3513298,14.0690456 L8.53909929,16.8812761 C7.79226637,17.6294356 6.81063872,18.0021888 5.8303376,18.0021888 Z M13.3644624,11.64416 C13.1110964,11.64416 12.8550773,11.5473237 12.6614048,11.3523247 C12.2727333,10.9636532 12.2727333,10.3348809 12.6614048,9.94620946 L15.4736353,7.13265238 C16.1912847,6.41500298 16.1912847,5.24633548 15.4736353,4.52868608 C14.7559859,3.81103668 13.5873184,3.81103668 12.869669,4.52868608 L10.056112,7.34224315 C9.66744047,7.73091464 9.03734165,7.73091464 8.64867016,7.34224315 C8.25999867,6.95357167 8.25999867,6.32347284 8.64867016,5.93480135 L11.4622272,3.12124428 C12.9545666,1.62625191 15.3874113,1.62625191 16.8797506,3.12124428 C18.3734165,4.61491013 18.3734165,7.04510181 16.8797506,8.53876766 L14.0675201,11.3523247 C13.8738476,11.5473237 13.619155,11.64416 13.3644624,11.64416 Z M8.06619354,12.9318167 C7.81150096,12.9318167 7.55680838,12.8349804 7.3631359,12.6399814 C6.97446442,12.2513099 6.97446442,11.6225376 7.3631359,11.2338662 L11.427605,7.16807057 C11.8162764,6.77939908 12.4463753,6.77939908 12.8350468,7.16807057 C13.2237182,7.55674206 13.2237182,8.18684088 12.8350468,8.57551237 L8.76925118,12.6399814 C8.5755787,12.8349804 8.32088612,12.9318167 8.06619354,12.9318167 Z" id="link-icon-1" fill="#575E75"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>copy-link-white</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="copy-link-white" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M5.8303376,18.0021888 C4.84870996,18.0021888 3.86840883,17.6294356 3.12024939,16.8812761 C1.62658354,15.3876103 1.62658354,12.9574186 3.12024939,11.4637527 L5.93380646,8.65019566 C6.32247795,8.26152418 6.95257677,8.26152418 7.34124826,8.65019566 C7.72991975,9.03886715 7.72991975,9.66896597 7.34124826,10.0576375 L4.52769119,12.8711945 C3.81004179,13.5888439 3.81004179,14.7575114 4.52769119,15.4751608 C5.24401406,16.1914837 6.41268157,16.1941368 7.13165749,15.4751608 L9.94521457,12.6629303 C10.3338861,12.2742588 10.9626584,12.2742588 11.3513298,12.6629303 C11.7400013,13.0516018 11.7400013,13.6803741 11.3513298,14.0690456 L8.53909929,16.8812761 C7.79226637,17.6294356 6.81063872,18.0021888 5.8303376,18.0021888 Z M13.3644624,11.64416 C13.1110964,11.64416 12.8550773,11.5473237 12.6614048,11.3523247 C12.2727333,10.9636532 12.2727333,10.3348809 12.6614048,9.94620946 L15.4736353,7.13265238 C16.1912847,6.41500298 16.1912847,5.24633548 15.4736353,4.52868608 C14.7559859,3.81103668 13.5873184,3.81103668 12.869669,4.52868608 L10.056112,7.34224315 C9.66744047,7.73091464 9.03734165,7.73091464 8.64867016,7.34224315 C8.25999867,6.95357167 8.25999867,6.32347284 8.64867016,5.93480135 L11.4622272,3.12124428 C12.9545666,1.62625191 15.3874113,1.62625191 16.8797506,3.12124428 C18.3734165,4.61491013 18.3734165,7.04510181 16.8797506,8.53876766 L14.0675201,11.3523247 C13.8738476,11.5473237 13.619155,11.64416 13.3644624,11.64416 Z M8.06619354,12.9318167 C7.81150096,12.9318167 7.55680838,12.8349804 7.3631359,12.6399814 C6.97446442,12.2513099 6.97446442,11.6225376 7.3631359,11.2338662 L11.427605,7.16807057 C11.8162764,6.77939908 12.4463753,6.77939908 12.8350468,7.16807057 C13.2237182,7.55674206 13.2237182,8.18684088 12.8350468,8.57551237 L8.76925118,12.6399814 C8.5755787,12.8349804 8.32088612,12.9318167 8.06619354,12.9318167 Z" id="link-icon-1" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>delete-gray</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="delete-gray" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group" transform="translate(3.000000, 2.500000)" stroke="#575E75">
<path d="M1,3 L13,3 L11.8900496,14.0995037 C11.8389294,14.6107055 11.4087639,15 10.8950124,15 L3.10498756,15 C2.59123611,15 2.16107055,14.6107055 2.10995037,14.0995037 L1,3 Z" id="Rectangle" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M7,11 L7,6" id="Line" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M9.5,11 L9.5,6" id="Line-Copy" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M4.5,11 L4.5,6" id="Line-Copy-2" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
<rect id="Rectangle-2" fill="#575E75" x="0" y="2.5" width="14" height="1" rx="0.5"></rect>
<path d="M6,0 L8,0 C8.55228475,-1.01453063e-16 9,0.44771525 9,1 L9,3 L5,3 L5,1 C5,0.44771525 5.44771525,1.01453063e-16 6,0 Z" id="Rectangle-3" stroke-width="1.5"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>fav-gray</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="fav-gray" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M11.3692316,3.18046683 L13.0137079,6.51146221 L16.6906559,7.04720832 C17.943533,7.22859321 18.4432423,8.76736172 17.5375191,9.65146291 L14.8756057,12.2449065 L15.5038461,15.9074398 C15.7176641,17.1543108 14.4083294,18.1056805 13.2887883,17.5170806 L9.99983573,15.7873174 L6.7108832,17.5170806 C5.59014079,18.1056805 4.28200737,17.1543108 4.4946241,15.9074398 L5.12406571,12.2449065 L2.46335357,9.65146291 C1.55642911,8.76736172 2.05613848,7.22859321 3.30901557,7.04720832 L6.98716482,6.51146221 L8.63043986,3.18046683 C9.19141168,2.04651095 10.8082598,2.04651095 11.3692316,3.18046683" id="Fill-1" fill="#575E75"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>fav-yellow</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="fav-yellow" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M11.3692316,3.18046683 L13.0137079,6.51146221 L16.6906559,7.04720832 C17.943533,7.22859321 18.4432423,8.76736172 17.5375191,9.65146291 L14.8756057,12.2449065 L15.5038461,15.9074398 C15.7176641,17.1543108 14.4083294,18.1056805 13.2887883,17.5170806 L9.99983573,15.7873174 L6.7108832,17.5170806 C5.59014079,18.1056805 4.28200737,17.1543108 4.4946241,15.9074398 L5.12406571,12.2449065 L2.46335357,9.65146291 C1.55642911,8.76736172 2.05613848,7.22859321 3.30901557,7.04720832 L6.98716482,6.51146221 L8.63043986,3.18046683 C9.19141168,2.04651095 10.8082598,2.04651095 11.3692316,3.18046683" id="Fill-1" fill="#FFBF00"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>love-gray</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="love-gray" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M17.9740815,8.16524321 C17.506512,13.4513048 11.5192871,17.6086957 10.0005184,17.6086957 C8.48174963,17.6086957 2.49348798,13.4513048 2.02695523,8.16524321 C2.01347761,7.99279306 2,7.82034292 2,7.64789278 C2,5.08489125 4.09317696,3 6.66740102,3 C7.97369274,3 9.16075941,3.53077469 10.0005184,4.40748231 C10.8402773,3.53077469 12.027344,3 13.3336357,3 C15.906823,3 18,5.08489125 18,7.64789278 C18,7.82034292 17.9865224,7.99279306 17.9740815,8.16524321 Z" id="Fill-1" fill="#575E75"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 959 B

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>love-red</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="love-red" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M17.9740815,8.16524321 C17.506512,13.4513048 11.5192871,17.6086957 10.0005184,17.6086957 C8.48174963,17.6086957 2.49348798,13.4513048 2.02695523,8.16524321 C2.01347761,7.99279306 2,7.82034292 2,7.64789278 C2,5.08489125 4.09317696,3 6.66740102,3 C7.97369274,3 9.16075941,3.53077469 10.0005184,4.40748231 C10.8402773,3.53077469 12.027344,3 13.3336357,3 C15.906823,3 18,5.08489125 18,7.64789278 C18,7.82034292 17.9865224,7.99279306 17.9740815,8.16524321 Z" id="Fill-1" fill="#FF6680"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 957 B

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>remix-gray</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="remix-gray" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M3.79735343,14.2387738 C2.44202813,12.0161502 2.33133423,9.04998717 3.52556841,6.69855452 C4.76300021,4.1712308 6.84548544,3.05103565 7.68243931,2.68681676 C8.18551159,2.45318367 8.71558237,2.27107423 9.28615093,2.13693508 L9.84592008,2.01612101 C10.2571974,1.93172883 10.6666748,2.18668205 10.7557699,2.59354119 C10.845765,3.00128868 10.5838794,3.40281779 10.1708022,3.49165166 L9.62633218,3.60891238 C9.17365713,3.71551303 8.73988103,3.86475393 8.31690435,4.06196513 C7.76703465,4.30003992 5.94823489,5.22124719 4.89889272,7.36569692 C4.10243662,8.93183812 3.86484971,11.4218516 5.11848062,13.4765791 C6.25421803,15.4557978 8.57968986,16.6692686 10.7854683,16.4649507 C12.8715533,16.3148214 14.7857478,14.926348 15.4571108,13.0874868 C16.1383733,11.3578912 15.6856982,9.5847671 14.9378394,8.58627435 C14.0369891,7.35592519 12.9156509,6.97749289 12.4755751,6.87178058 C12.4098788,6.85223712 10.8691637,6.38941264 9.50843868,7.07076845 C8.92257097,7.3514835 8.16481273,7.98309234 7.7589351,8.93183812 C7.32065925,9.91167575 7.434053,11.1713401 8.02802027,12.0081552 C8.62558733,12.9053773 9.75232523,13.4135071 10.7215718,13.2411694 C11.6863186,13.0892634 12.3387827,12.3714857 12.4935742,11.7407652 C12.6753641,11.0629628 12.3963795,10.4899843 12.1785915,10.2838897 C11.8087119,9.91878246 11.4892295,9.91256409 11.4757303,9.91167575 C11.3245386,9.90723406 11.2498427,9.91878246 11.2048452,9.92588917 C11.0320547,9.98896122 10.7872682,10.1275421 10.7152722,10.2732296 C10.7026729,10.2972148 10.6702746,10.3629518 10.7323712,10.5272945 C10.880863,10.9172752 10.6801741,11.3534495 10.2850959,11.5000254 C9.89181755,11.6474897 9.44904195,11.4493901 9.29965018,11.0585211 C9.05396372,10.4118105 9.18985623,9.90545738 9.34734755,9.59453882 C9.75862489,8.78526223 10.7134723,8.49211044 10.8214663,8.46101859 C10.8709636,8.44591683 10.9231607,8.43703344 10.9744579,8.43259175 C11.0797521,8.41660165 11.2651419,8.39172816 11.516228,8.40149989 C12.0912963,8.4086066 12.7464602,8.7088651 13.2486325,9.20544645 C13.8416999,9.76509986 14.3060743,10.8897367 13.9766924,12.1120908 C13.6554101,13.4206138 12.4206782,14.5026104 10.9798576,14.7291368 C9.43014299,15.0054101 7.68513916,14.2414388 6.76358995,12.8565187 C5.87533891,11.6084027 5.70524828,9.7819783 6.35501247,8.33309781 C7.06777319,6.66479765 8.42939815,5.90970972 8.82897612,5.71782855 C10.7503702,4.75842271 12.804057,5.39180823 12.8904523,5.41845839 C13.4430218,5.54904419 14.9792372,6.06339232 16.1734713,7.69527059 C17.0914208,8.92295473 17.8356797,11.215757 16.8898319,13.6160483 C16.0258795,15.9816944 13.566315,17.7788037 10.9141612,17.9697965 C10.7062727,17.9893399 10.4956843,18 10.2859958,18 C7.71213768,18 5.10498136,16.5164743 3.79735343,14.2387738 Z" id="Fill-1" fill="#575E75"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>remix-white</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="remix-white" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M3.79735343,14.2387738 C2.44202813,12.0161502 2.33133423,9.04998717 3.52556841,6.69855452 C4.76300021,4.1712308 6.84548544,3.05103565 7.68243931,2.68681676 C8.18551159,2.45318367 8.71558237,2.27107423 9.28615093,2.13693508 L9.84592008,2.01612101 C10.2571974,1.93172883 10.6666748,2.18668205 10.7557699,2.59354119 C10.845765,3.00128868 10.5838794,3.40281779 10.1708022,3.49165166 L9.62633218,3.60891238 C9.17365713,3.71551303 8.73988103,3.86475393 8.31690435,4.06196513 C7.76703465,4.30003992 5.94823489,5.22124719 4.89889272,7.36569692 C4.10243662,8.93183812 3.86484971,11.4218516 5.11848062,13.4765791 C6.25421803,15.4557978 8.57968986,16.6692686 10.7854683,16.4649507 C12.8715533,16.3148214 14.7857478,14.926348 15.4571108,13.0874868 C16.1383733,11.3578912 15.6856982,9.5847671 14.9378394,8.58627435 C14.0369891,7.35592519 12.9156509,6.97749289 12.4755751,6.87178058 C12.4098788,6.85223712 10.8691637,6.38941264 9.50843868,7.07076845 C8.92257097,7.3514835 8.16481273,7.98309234 7.7589351,8.93183812 C7.32065925,9.91167575 7.434053,11.1713401 8.02802027,12.0081552 C8.62558733,12.9053773 9.75232523,13.4135071 10.7215718,13.2411694 C11.6863186,13.0892634 12.3387827,12.3714857 12.4935742,11.7407652 C12.6753641,11.0629628 12.3963795,10.4899843 12.1785915,10.2838897 C11.8087119,9.91878246 11.4892295,9.91256409 11.4757303,9.91167575 C11.3245386,9.90723406 11.2498427,9.91878246 11.2048452,9.92588917 C11.0320547,9.98896122 10.7872682,10.1275421 10.7152722,10.2732296 C10.7026729,10.2972148 10.6702746,10.3629518 10.7323712,10.5272945 C10.880863,10.9172752 10.6801741,11.3534495 10.2850959,11.5000254 C9.89181755,11.6474897 9.44904195,11.4493901 9.29965018,11.0585211 C9.05396372,10.4118105 9.18985623,9.90545738 9.34734755,9.59453882 C9.75862489,8.78526223 10.7134723,8.49211044 10.8214663,8.46101859 C10.8709636,8.44591683 10.9231607,8.43703344 10.9744579,8.43259175 C11.0797521,8.41660165 11.2651419,8.39172816 11.516228,8.40149989 C12.0912963,8.4086066 12.7464602,8.7088651 13.2486325,9.20544645 C13.8416999,9.76509986 14.3060743,10.8897367 13.9766924,12.1120908 C13.6554101,13.4206138 12.4206782,14.5026104 10.9798576,14.7291368 C9.43014299,15.0054101 7.68513916,14.2414388 6.76358995,12.8565187 C5.87533891,11.6084027 5.70524828,9.7819783 6.35501247,8.33309781 C7.06777319,6.66479765 8.42939815,5.90970972 8.82897612,5.71782855 C10.7503702,4.75842271 12.804057,5.39180823 12.8904523,5.41845839 C13.4430218,5.54904419 14.9792372,6.06339232 16.1734713,7.69527059 C17.0914208,8.92295473 17.8356797,11.215757 16.8898319,13.6160483 C16.0258795,15.9816944 13.566315,17.7788037 10.9141612,17.9697965 C10.7062727,17.9893399 10.4956843,18 10.2859958,18 C7.71213768,18 5.10498136,16.5164743 3.79735343,14.2387738 Z" id="Fill-1" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>report-gray</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="report-gray" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M9.93975407,12.6597613 C8.46423356,12.6597613 7.2696347,13.8543601 7.2696347,15.3298806 C7.2696347,16.8054011 8.46423356,18 9.93975407,18 C11.4152746,18 12.6098734,16.8054011 12.6098734,15.3298806 C12.6098734,13.8543601 11.4152746,12.6597613 9.93975407,12.6597613 M11.4725499,10.2269663 C10.7934286,11.7478886 9.08607954,11.7478886 8.40695827,10.2269663 L6.23867952,5.39847481 C5.55955826,3.88804156 6.41050539,2 7.77147532,2 L12.1080328,2 C13.4690027,2 14.3199499,3.88804156 13.6408286,5.39847481 L11.4725499,10.2269663 Z" id="Fill-1" fill="#575E75"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>report-white</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="report-white" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M9.93975407,12.6597613 C8.46423356,12.6597613 7.2696347,13.8543601 7.2696347,15.3298806 C7.2696347,16.8054011 8.46423356,18 9.93975407,18 C11.4152746,18 12.6098734,16.8054011 12.6098734,15.3298806 C12.6098734,13.8543601 11.4152746,12.6597613 9.93975407,12.6597613 M11.4725499,10.2269663 C10.7934286,11.7478886 9.08607954,11.7478886 8.40695827,10.2269663 L6.23867952,5.39847481 C5.55955826,3.88804156 6.41050539,2 7.77147532,2 L12.1080328,2 C13.4690027,2 14.3199499,3.88804156 13.6408286,5.39847481 L11.4725499,10.2269663 Z" id="Fill-1" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>restore-gray</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="restore-gray" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M6.28386991,15.293449 C6.28386991,15.709633 5.94481309,16.0470795 5.52664301,16.0470795 C5.10847293,16.0470795 4.75811422,15.709633 4.75811422,15.293449 C4.75811422,14.8660168 5.10847293,14.5274455 5.52664301,14.5274455 C5.94481309,14.5274455 6.28386991,14.8660168 6.28386991,15.293449 Z M9.38081491,17.0256743 C9.38081491,17.4980994 8.99655052,17.8805388 8.52187097,17.8805388 C8.04719142,17.8805388 7.67422891,17.4980994 7.67422891,17.0256743 C7.67422891,16.5532492 8.04719142,16.1820581 8.52187097,16.1820581 C8.99655052,16.1820581 9.38081491,16.5532492 9.38081491,17.0256743 Z M16.0493845,15.394458 C16.0493845,15.9568688 15.5860068,16.4180457 15.0096102,16.4180457 C14.4320834,16.4180457 13.969836,15.9568688 13.969836,15.394458 C13.969836,14.820799 14.4320834,14.3596221 15.0096102,14.3596221 C15.5860068,14.3596221 16.0493845,14.820799 16.0493845,15.394458 Z M17.9477636,12.4473128 C17.9477636,13.077213 17.4391784,13.5721345 16.8175742,13.5721345 C16.19597,13.5721345 15.6873848,13.077213 15.6873848,12.4473128 C15.6873848,11.828661 16.19597,11.3224912 16.8175742,11.3224912 C17.4391784,11.3224912 17.9477636,11.828661 17.9477636,12.4473128 Z M12.9302878,17.0586316 C12.9302878,17.5760495 12.4996856,18.0034818 11.9797985,18.0034818 C11.4599113,18.0034818 11.0417413,17.5760495 11.0417413,17.0586316 C11.0417413,16.5412136 11.4599113,16.1137814 11.9797985,16.1137814 C12.4996856,16.1137814 12.9302878,16.5412136 12.9302878,17.0586316 Z M11.5738344,5.58635083 C10.0469485,5.32764186 8.52232304,5.82256338 7.48254879,6.77866176 L8.80487039,8.09357825 C9.31345562,8.6109962 8.95179502,9.48948189 8.21604171,9.48948189 L2.82616845,9.48948189 C2.3729625,9.48948189 2,9.11829075 2,8.66723728 L2,3.30296293 C2,2.57070405 2.88267792,2.21188595 3.40256505,2.71693086 L4.53275445,3.84175249 C5.56122681,3.04312913 6.75809738,2.4694701 8.01373781,2.19951291 C9.47168214,1.88568767 10.9850058,1.94192876 12.3762689,2.36936097 C15.1780084,3.2129772 17.3479721,5.55260619 17.9695763,8.22968166 C18.1176311,8.87082999 17.7107629,9.52322654 17.0654247,9.66945335 C16.4664244,9.81568016 15.8798561,9.47823367 15.6651201,8.92707107 L15.6651201,8.91582286 C14.9757045,7.12623165 13.3143261,5.84393499 11.5738344,5.58635083 Z" id="restore" fill="#575E75" transform="translate(10.000000, 10.001741) scale(-1, 1) translate(-10.000000, -10.001741) "></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>revised-date-gray</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="revised-date-gray" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group" transform="translate(2.000000, 1.500000)" fill="#575E75">
<path d="M9.4784,16.8662667 L5.41173333,12.7862667 C5.17173333,12.5609333 5.17173333,12.1729333 5.41173333,11.9342667 L9.4784,7.85293333 C9.86506667,7.4796 10.5184,7.74626667 10.5184,8.29293333 L10.5184,10.4276 C11.2517333,10.3462667 11.9850667,10.0409333 12.5850667,9.46626667 C13.4517333,8.6796 13.9584,7.37426667 13.7984,6.01293333 L13.7850667,5.9876 C13.7317333,5.53293333 14.0517333,5.1196 14.5050667,5.06626667 C14.8917333,5.02626667 15.2384,5.2396 15.3850667,5.58626667 C16.0650667,7.30626667 15.9184,9.45293333 14.8250667,11.1862667 C13.9184,12.6676 12.3450667,13.8129333 10.5184,14.2142667 L10.5184,16.4409333 C10.5184,16.9729333 9.86506667,17.2529333 9.4784,16.8662667" id="Fill-1"></path>
<path d="M10.6665333,4.96 L1.3332,4.96 L1.3332,2.96 C1.3332,2.58666667 1.62653333,2.29333333 1.99986667,2.29333333 L2.95986667,2.29333333 L2.95986667,2.57333333 C2.95986667,2.94666667 3.2532,3.24 3.62653333,3.24 C3.98653333,3.24 4.2932,2.94666667 4.2932,2.57333333 L4.2932,2.29333333 L7.70653333,2.29333333 L7.70653333,2.57333333 C7.70653333,2.94666667 7.99986667,3.24 8.3732,3.24 C8.7332,3.24 9.03986667,2.94666667 9.03986667,2.57333333 L9.03986667,2.29333333 L9.99986667,2.29333333 C10.3598667,2.29333333 10.6665333,2.58666667 10.6665333,2.96 L10.6665333,4.96 Z M9.99986667,0.96 L9.03986667,0.96 L9.03986667,0.666666667 C9.03986667,0.293333333 8.7332,0 8.3732,0 C7.99986667,0 7.70653333,0.293333333 7.70653333,0.666666667 L7.70653333,0.96 L4.2932,0.96 L4.2932,0.666666667 C4.2932,0.293333333 3.98653333,0 3.62653333,0 C3.2532,0 2.95986667,0.293333333 2.95986667,0.666666667 L2.95986667,0.96 L1.99986667,0.96 C0.8932,0.96 -0.000133333333,1.85333333 -0.000133333333,2.96 L-0.000133333333,10.96 C-0.000133333333,12.0666667 0.8932,12.96 1.99986667,12.96 L3.2932,12.96 C3.6532,12.96 3.95986667,12.6666667 3.95986667,12.2933333 C3.95986667,11.92 3.6532,11.6266667 3.2932,11.6266667 L1.99986667,11.6266667 C1.62653333,11.6266667 1.3332,11.32 1.3332,10.96 L1.3332,6.29333333 L11.3332,6.29333333 C11.6932,6.29333333 11.9998667,5.98666667 11.9998667,5.62666667 L11.9998667,2.96 C11.9998667,1.85333333 11.0932,0.96 9.99986667,0.96 Z" id="Fill-4"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>scripts-gray</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="scripts-gray" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M13.1968,8.07504 L13.1968,11.28304 C13.1968,11.50384 13.0176,11.68304 12.7968,11.68304 L8.55759995,11.68304 C8.45119995,11.68304 8.34959995,11.72464 8.27519995,11.79984 L7.71679995,12.35824 C7.64239995,12.43264 7.54079995,12.47504 7.43439995,12.47504 L5.36559995,12.47504 C5.25999995,12.47504 5.15839995,12.43264 5.08239995,12.35824 L4.52559995,11.79984 C4.45039995,11.72464 4.34799995,11.68304 4.24239995,11.68304 L3.19999995,11.68304 C2.97919995,11.68304 2.79999995,11.50384 2.79999995,11.28304 L2.79999995,8.07504 C2.79999995,7.85424 2.97919995,7.67504 3.19999995,7.67504 L4.23439995,7.67504 C4.34079995,7.67504 4.44239995,7.71744 4.51679995,7.79184 L5.08239995,8.35824 C5.15839995,8.43264 5.25999995,8.47504 5.36559995,8.47504 L7.43439995,8.47504 C7.54079995,8.47504 7.64239995,8.43264 7.71679995,8.35824 L8.28239995,7.79184 C8.35839995,7.71744 8.45999995,7.67504 8.56559995,7.67504 L12.7968,7.67504 C13.0176,7.67504 13.1968,7.85424 13.1968,8.07504 M15.2776,13.6 L15.2776,16.808 C15.2776,17.0288 15.0984,17.208 14.8776,17.208 L8.55759995,17.208 C8.45119995,17.208 8.34959995,17.2496 8.27519995,17.3248 L7.71679995,17.8832 C7.64239995,17.9576 7.54079995,18 7.43439995,18 L5.36559995,18 C5.25999995,18 5.15839995,17.9576 5.08239995,17.8832 L4.52559995,17.3248 C4.45039995,17.2496 4.34799995,17.208 4.24239995,17.208 L3.19999995,17.208 C2.97919995,17.208 2.79999995,17.0288 2.79999995,16.808 L2.79999995,13.6 C2.79999995,13.3792 2.97919995,13.2 3.19999995,13.2 L4.23439995,13.2 C4.34079995,13.2 4.44239995,13.2424 4.51679995,13.3168 L5.08239995,13.8832 C5.15839995,13.9576 5.25999995,14 5.36559995,14 L7.43439995,14 C7.54079995,14 7.64239995,13.9576 7.71679995,13.8832 L8.28239995,13.3168 C8.35839995,13.2424 8.45999995,13.2 8.56559995,13.2 L14.8776,13.2 C15.0984,13.2 15.2776,13.3792 15.2776,13.6 Z M17.20032,2.4 L17.20032,5.608 C17.20032,5.8288 17.02032,6.008 16.80032,6.008 L8.55791995,6.008 C8.45151995,6.008 8.34991995,6.0496 8.27471995,6.1248 L7.71711995,6.6832 C7.64191995,6.7576 7.54031995,6.8 7.43391995,6.8 L5.36591995,6.8 C5.25951995,6.8 5.15791995,6.7576 5.08271995,6.6832 L4.52511995,6.1248 C4.44991995,6.0496 4.34831995,6.008 4.24271995,6.008 L3.20031995,6.008 C2.97951995,6.008 2.80031995,5.8288 2.80031995,5.608 L2.80031995,2.4 C2.80031995,2.1792 2.97951995,2 3.20031995,2 L4.23391995,2 C4.34031995,2 4.44191995,2.0424 4.51711995,2.1168 L5.08271995,2.6832 C5.15791995,2.7576 5.25951995,2.8 5.36591995,2.8 L7.43391995,2.8 C7.54031995,2.8 7.64191995,2.7576 7.71711995,2.6832 L8.28271995,2.1168 C8.35791995,2.0424 8.45951995,2 8.56591995,2 L16.80032,2 C17.02032,2 17.20032,2.1792 17.20032,2.4 Z" id="Scripts" fill="#575E75"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3 KiB

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>see-inside-white</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="see-inside-white" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M11.3762804,5.25869898 C10.040244,5.0236191 8.70618543,5.47333712 7.7963753,6.34211057 L8.95341644,7.53692958 C9.39843226,8.00708932 9.08197657,8.80533881 8.43917593,8.80533881 L3.72200821,8.80533881 C3.32643859,8.80533881 3.00009366,8.46805029 3.00009366,8.05819364 L3.00009366,3.18386357 C3.00009366,2.51848532 3.77145442,2.19243975 4.22635948,2.65135655 L5.21528353,3.67344296 C6.11520442,2.94776161 7.16346391,2.42649754 8.26116961,2.1811968 C9.53688163,1.8960347 10.8610509,1.94713902 12.0784164,2.33553185 C14.5309481,3.10209666 16.4296823,5.22803638 16.9735905,7.66060203 C17.1021506,8.24319128 16.746138,8.8360014 16.1824513,8.96887263 C15.6583215,9.10174387 15.144081,8.79511794 14.9561854,8.2942956 L14.9561854,8.28407474 C14.3529418,6.65793527 12.8992234,5.49275676 11.3762804,5.25869898 Z M8.62371963,14.7412181 C9.9587671,14.9752824 11.2938146,14.526574 12.2036247,13.6577763 L11.0465836,12.4619018 C10.6015677,11.991729 10.9170345,11.1944793 11.5608241,11.1944793 L16.2770029,11.1944793 C16.6735614,11.1944793 16.9999063,11.5317772 16.9999063,11.9406232 L16.9999063,16.8161114 C16.9999063,17.4804861 16.2275567,17.8075629 15.7726516,17.3476112 L14.7837275,16.3254963 C13.8838067,17.0511979 12.8365361,17.5724765 11.7378415,17.817784 C10.4621294,18.1039762 9.13796014,18.0528705 7.92158356,17.6644668 C5.46905191,16.8978806 3.57031774,14.7718816 3.02640951,12.339248 C2.89784938,11.7566425 3.25287312,11.1638159 3.81754875,11.0309409 C4.3416785,10.898066 4.85493008,11.2047005 5.04381457,11.7055368 L5.04381457,11.7157579 C5.64606932,13.3409207 7.1007766,14.5061317 8.62371963,14.7412181 Z" id="Combined-Shape" fill="#FFFFFF" transform="translate(10.000000, 9.999906) rotate(90.000000) translate(-10.000000, -9.999906) "></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>share-white</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="share-white" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<rect id="Rectangle" stroke="#FFFFFF" stroke-width="2" x="3" y="3" width="14" height="14" rx="4"></rect>
</g>
</svg>

After

Width:  |  Height:  |  Size: 570 B

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>studio-add-white</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="studio-add-white" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<rect id="Rectangle" stroke="#FFFFFF" stroke-width="2" x="3" y="3" width="14" height="14" rx="4"></rect>
</g>
</svg>

After

Width:  |  Height:  |  Size: 580 B

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>views-gray</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="views-gray" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="views" transform="translate(2.000000, 3.800000)" fill="#575E75" fill-rule="nonzero">
<path d="M15.4390052,4.41681127 C16.1720223,5.4489779 16.2018258,7.14653628 15.4390052,8.15461725 C15.4390052,8.15461725 13.1136459,12.5714286 7.99999999,12.5714286 C2.88635412,12.5714286 0.560994788,8.15461725 0.560994788,8.15461725 C-0.172022306,7.12245063 -0.201825795,5.42489224 0.560994788,4.41681127 C0.560994788,4.41681127 2.88635412,4.49037158e-16 7.99999999,0 C13.1136459,0 15.4390052,4.41681127 15.4390052,4.41681127 Z M7.99873614,10.855879 C10.5231174,10.855879 12.5695328,8.80946363 12.5695328,6.28508235 C12.5695328,3.76070107 10.5231174,1.71428571 7.99873614,1.71428571 C5.47435486,1.71428571 3.4279395,3.76070107 3.4279395,6.28508235 C3.4279395,8.80946363 5.47435486,10.855879 7.99873614,10.855879 Z" id="Combined-Shape"></path>
<circle id="Oval" cx="7.88571429" cy="6.28571429" r="2.28571429"></circle>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB