1
0
mirror of https://github.com/chinchang/web-maker.git synced 2025-03-24 04:29:40 +01:00

add fork in header

This commit is contained in:
Kushagra Gour 2024-04-28 17:29:46 +05:30
parent 3e9a947527
commit f28f837fda
4 changed files with 72 additions and 37 deletions

View File

@ -128,6 +128,9 @@ export function Icons() {
<symbol id="check-circle" viewBox="0 0 24 24">
<path d="M12 2C6.5 2 2 6.5 2 12S6.5 22 12 22 22 17.5 22 12 17.5 2 12 2M10 17L5 12L6.41 10.59L10 14.17L17.59 6.58L19 8L10 17Z" />
</symbol>
<symbol id="fork" viewBox="0 0 24 24">
<path d="M13 14c-3.36 0-4.46 1.35-4.82 2.24C9.25 16.7 10 17.76 10 19a3 3 0 0 1-3 3 3 3 0 0 1-3-3c0-1.31.83-2.42 2-2.83V7.83A2.99 2.99 0 0 1 4 5a3 3 0 0 1 3-3 3 3 0 0 1 3 3c0 1.31-.83 2.42-2 2.83v5.29c.88-.65 2.16-1.12 4-1.12 2.67 0 3.56-1.34 3.85-2.23A3.006 3.006 0 0 1 14 7a3 3 0 0 1 3-3 3 3 0 0 1 3 3c0 1.34-.88 2.5-2.09 2.86C17.65 11.29 16.68 14 13 14m-6 4a1 1 0 0 0-1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0-1-1M7 4a1 1 0 0 0-1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0-1-1m10 2a1 1 0 0 0-1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0-1-1Z" />
</symbol>
<symbol id="loader-icon" viewBox="0 0 44 44">
{/* By Sam Herbert (@sherb), for everyone. More http://goo.gl/7AJzbL */}
<g fill="none" fillRule="evenodd" strokeWidth={10}>

View File

@ -4,16 +4,30 @@ import { Trans, NumberFormat, t } from '@lingui/macro';
import { I18n } from '@lingui/react';
import { ProBadge } from './ProBadge';
import { HStack, Stack } from './Stack';
import { Icon } from './Icons';
const DEFAULT_PROFILE_IMG =
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23ccc' d='M12,19.2C9.5,19.2 7.29,17.92 6,16C6.03,14 10,12.9 12,12.9C14,12.9 17.97,14 18,16C16.71,17.92 14.5,19.2 12,19.2M12,5A3,3 0 0,1 15,8A3,3 0 0,1 12,11A3,3 0 0,1 9,8A3,3 0 0,1 12,5M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z'/%3E%3C/svg%3E";
export function MainHeader(props) {
export function MainHeader({
user,
currentItem,
titleInputBlurHandler,
runBtnClickHandler,
assetsBtnHandler,
isFileMode,
onItemFork,
...props
}) {
const isAutoPreviewOn =
window.forcedSettings.autoPreview !== undefined
? window.forcedSettings
: props.isAutoPreviewOn;
const isNotMine =
currentItem.createdBy && user?.uid !== currentItem.createdBy;
// console.log(33, currentItem, user?.uid);
return (
<I18n>
{({ i18n }) => (
@ -23,15 +37,15 @@ export function MainHeader(props) {
id="titleInput"
title="Click to edit"
class="item-title-input"
value={props.currentItem.title}
onBlur={props.titleInputBlurHandler}
value={currentItem.title}
onBlur={titleInputBlurHandler}
/>
<div class="main-header__btn-wrap flex flex-v-center">
{!isAutoPreviewOn && (
<button
class="btn btn btn--dark flex flex-v-center hint--rounded hint--bottom-left"
aria-label={i18n._(t`Run preview (Ctrl/⌘ + Shift + 5)`)}
onClick={props.runBtnClickHandler}
onClick={runBtnClickHandler}
>
<svg>
<use xlinkHref="#play-icon" />
@ -39,9 +53,8 @@ export function MainHeader(props) {
<Trans>Run</Trans>
</button>
)}
<Button
onClick={props.assetsBtnHandler}
onClick={assetsBtnHandler}
data-event-category="ui"
data-event-action="addLibraryButtonClick"
data-testid="addLibraryButton"
@ -50,8 +63,7 @@ export function MainHeader(props) {
>
<Trans>Assets</Trans>
</Button>
{!props.isFileMode && (
{!isFileMode && (
<Button
onClick={props.addLibraryBtnHandler}
data-event-category="ui"
@ -72,7 +84,6 @@ export function MainHeader(props) {
</span>
</Button>
)}
<button
class="btn btn--dark hint--bottom-left"
aria-label={i18n._(t`Share this creation publicly`)}
@ -82,9 +93,7 @@ export function MainHeader(props) {
<svg
viewBox="0 0 24 24"
style={{
fill: props.currentItem.isPublic
? 'limegreen'
: 'currentColor'
fill: currentItem.isPublic ? 'limegreen' : 'currentColor'
}}
strokeWidth="2"
strokeLinecap="round"
@ -92,7 +101,17 @@ export function MainHeader(props) {
>
<path d="M18 16.08C17.24 16.08 16.56 16.38 16.04 16.85L8.91 12.7C8.96 12.47 9 12.24 9 12S8.96 11.53 8.91 11.3L15.96 7.19C16.5 7.69 17.21 8 18 8C19.66 8 21 6.66 21 5S19.66 2 18 2 15 3.34 15 5C15 5.24 15.04 5.47 15.09 5.7L8.04 9.81C7.5 9.31 6.79 9 6 9C4.34 9 3 10.34 3 12S4.34 15 6 15C6.79 15 7.5 14.69 8.04 14.19L15.16 18.34C15.11 18.55 15.08 18.77 15.08 19C15.08 20.61 16.39 21.91 18 21.91S20.92 20.61 20.92 19C20.92 17.39 19.61 16.08 18 16.08M18 4C18.55 4 19 4.45 19 5S18.55 6 18 6 17 5.55 17 5 17.45 4 18 4M6 13C5.45 13 5 12.55 5 12S5.45 11 6 11 7 11.45 7 12 6.55 13 6 13M18 20C17.45 20 17 19.55 17 19S17.45 18 18 18 19 18.45 19 19 18.55 20 18 20Z" />
</svg>
{props.currentItem.isPublic ? null : <Trans>Share</Trans>}
{currentItem.isPublic ? null : <Trans>Share</Trans>}
</button>
<button
class="btn btn--dark hint--bottom-left"
aria-label={i18n._(t`Fork this creation`)}
data-testid="headerForkButton"
onClick={onItemFork}
>
<Icon name="fork" />
<Trans>Fork</Trans>
</button>
<button
@ -106,22 +125,25 @@ export function MainHeader(props) {
</svg>
<Trans>New</Trans>
</button>
<button
id="saveBtn"
class={`btn btn--dark hint--rounded hint--bottom-left ${
props.isSaving ? 'is-loading' : ''
} ${props.unsavedEditCount ? 'is-marked' : 0}`}
aria-label={i18n._(t`Save current creation (Ctrl/⌘ + S)`)}
onClick={props.saveBtnHandler}
>
<svg viewBox="0 0 24 24">
<path d="M15,9H5V5H15M12,19A3,3 0 0,1 9,16A3,3 0 0,1 12,13A3,3 0 0,1 15,16A3,3 0 0,1 12,19M17,3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V7L17,3Z" />
</svg>
<svg class="btn-loader" width="15" height="15" stroke="#fff">
<use xlinkHref="#loader-icon" />
</svg>
<Trans>Save</Trans>
</button>
{!isNotMine && (
<button
id="saveBtn"
class={`btn btn--dark hint--rounded hint--bottom-left ${
props.isSaving ? 'is-loading' : ''
} ${props.unsavedEditCount ? 'is-marked' : 0}`}
aria-label={i18n._(t`Save current creation (Ctrl/⌘ + S)`)}
onClick={props.saveBtnHandler}
>
<svg viewBox="0 0 24 24">
<path d="M15,9H5V5H15M12,19A3,3 0 0,1 9,16A3,3 0 0,1 12,13A3,3 0 0,1 15,16A3,3 0 0,1 12,19M17,3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V7L17,3Z" />
</svg>
<svg class="btn-loader" width="15" height="15" stroke="#fff">
<use xlinkHref="#loader-icon" />
</svg>
<Trans>Save</Trans>
</button>
)}
<button
id="openItemsBtn"
class={`btn btn--dark hint--rounded hint--bottom-left ${
@ -138,7 +160,7 @@ export function MainHeader(props) {
</svg>
<Trans>Open</Trans>
</button>
{!props.user ? (
{!user ? (
<Button
onClick={props.loginBtnHandler}
data-event-category="ui"
@ -160,14 +182,10 @@ export function MainHeader(props) {
<img
id="headerAvatarImg"
width="20"
src={
props.user
? props.user.photoURL || DEFAULT_PROFILE_IMG
: ''
}
src={user ? user.photoURL || DEFAULT_PROFILE_IMG : ''}
class="main-header__avatar-img"
/>
{props.user?.isPro ? <ProBadge /> : null}
{user?.isPro ? <ProBadge /> : null}
</HStack>
</Button>
)}

View File

@ -383,9 +383,11 @@ export default class App extends Component {
}
const fork = JSON.parse(JSON.stringify(sourceItem));
delete fork.id;
delete fork.createdBy;
fork.title = '(Forked) ' + sourceItem.title;
fork.updatedOn = Date.now();
this.setCurrentItem(fork).then(() => this.refreshEditor());
route('/create');
alertsService.add(`"${sourceItem.title}" was forked`);
trackEvent('fn', 'itemForked');
}
@ -936,6 +938,15 @@ export default class App extends Component {
var isNewItem = !this.state.currentItem.id;
this.state.currentItem.id =
this.state.currentItem.id || 'item-' + generateRandomId();
if (
this.state.currentItem.createdBy &&
this.state.currentItem.createdBy !== this.state.user.uid
) {
alertsService.add(
'You cannot save this item as it was created by someone else. Fork it to save it as your own.'
);
return;
}
this.setState({
isSaving: true
});
@ -1697,6 +1708,9 @@ export default class App extends Component {
isFileMode={
this.state.currentItem && this.state.currentItem.files
}
onItemFork={() => {
this.forkItem(this.state.currentItem);
}}
/>
{this.state.currentItem && this.state.currentItem.files ? (
<ContentWrapFiles

View File

@ -157,7 +157,7 @@ function getArrayFromQuerySnapshot(querySnapshot) {
return {};
}
const user = doc.data();
Object.assign(window.user, user);
window.user = { ...window.user, ...user };
return user;
});
}