1
0
mirror of https://github.com/chinchang/web-maker.git synced 2025-03-24 12:39:51 +01:00

add share modal

This commit is contained in:
Kushagra Gour 2024-03-04 23:26:36 +05:30
parent 7a0202729f
commit e89c2348e4
5 changed files with 141 additions and 12 deletions

View File

@ -23,7 +23,7 @@ export function MainHeader(props) {
id="titleInput"
title="Click to edit"
class="item-title-input"
value={props.title}
value={props.currentItem.title}
onBlur={props.titleInputBlurHandler}
/>
<div class="main-header__btn-wrap flex flex-v-center">
@ -73,6 +73,24 @@ export function MainHeader(props) {
</Button>
)}
<button
class="btn btn--dark hint--rounded hint--bottom-left"
aria-label={i18n._(t`Start a new creation`)}
data-testid="newButton"
onClick={props.shareBtnHandler}
>
<svg
viewBox="0 0 24 24"
fill={props.currentItem.isPublic ? 'green' : 'currentColor'}
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<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>
<Trans>Share</Trans>
</button>
<button
class="btn btn--dark hint--rounded hint--bottom-left"
aria-label={i18n._(t`Start a new creation`)}

71
src/components/Share.jsx Normal file
View File

@ -0,0 +1,71 @@
import { useEffect, useState } from 'preact/hooks';
import { ProBadge } from './ProBadge';
import { HStack, Stack, VStack } from './Stack';
import Switch from './Switch';
import { itemService } from '../itemService';
import { alertsService } from '../notifications';
const FREE_PUBLIC_ITEM_COUNT = 1;
export function Share({ user, item, onVisibilityChange }) {
const [publicItemCount, setPublicItemCount] = useState(0);
useEffect(() => {
window.db.getPublicItemCount(user.uid).then(c => {
setPublicItemCount(c);
console.log(c);
});
}, []);
const [val, setVal] = useState(item.isPublic);
const onChange = async e => {
const newVal = e.target.checked;
setVal(newVal);
if (newVal) {
const token = await window.user.getIdToken();
const res = await fetch(
`http://127.0.0.1:5001/web-maker-app/us-central1/toggleVisibility?token=${token}&itemId=${item.id}`
);
console.log(res.status);
if (res.status >= 200 && res.status < 400) {
setPublicItemCount(publicItemCount + 1);
onVisibilityChange(true);
alertsService.add('Visiblity set to public');
} else {
alertsService.add('Could not set visiblity to public');
}
} else {
itemService.setItem(item.id, { isPublic: false });
setPublicItemCount(publicItemCount - 1);
onVisibilityChange(false);
alertsService.add('Visiblity set to private');
}
};
return (
<VStack gap={4} align="stretch">
<VStack gap={1} align="stretch">
<Switch checked={val} onChange={onChange}>
Go public?
</Switch>
{item.isPublic && (
<p>
Public at{' '}
<a href={`https://webmaker.app/create/${item.id}`} target="_blank">
https://webmaker.app/create/{item.id}
</a>
</p>
)}
</VStack>
<VStack gap={1} align="stretch">
<p>
You have {FREE_PUBLIC_ITEM_COUNT - publicItemCount}/
{FREE_PUBLIC_ITEM_COUNT} public creations left.
</p>
<p>
For unlimited public creations, upgrade to <ProBadge />
</p>
</VStack>
</VStack>
);
}

View File

@ -70,6 +70,7 @@ import { commandPaletteService } from '../commandPaletteService';
import { I18nProvider } from '@lingui/react';
import { Assets } from './Assets.jsx';
import { LocalStorageKeys } from '../constants.js';
import { Share } from './Share.jsx';
if (module.hot) {
require('preact/debug');
@ -119,7 +120,8 @@ export default class App extends Component {
isJs13KModalOpen: false,
isCreateNewModalOpen: false,
isCommandPaletteOpen: false,
isAssetsOpen: false
isAssetsOpen: false,
isShareModalOpen: false
};
this.state = {
isSavedItemPaneOpen: false,
@ -169,14 +171,14 @@ export default class App extends Component {
window.user = savedUser;
}
firebase.auth().onAuthStateChanged(user => {
firebase.auth().onAuthStateChanged(authUser => {
this.setState({ isLoginModalOpen: false });
if (user) {
log('You are -> ', user);
if (authUser) {
log('You are -> ', authUser);
alertsService.add('You are now logged in!');
this.setState({ user });
window.user = user;
window.localStorage.setItem('user', user);
this.setState({ user: authUser });
window.user = authUser;
window.localStorage.setItem('user', authUser);
if (!window.localStorage[LocalStorageKeys.ASKED_TO_IMPORT_CREATIONS]) {
this.fetchItems(false, true).then(items => {
if (!items.length) {
@ -190,11 +192,14 @@ export default class App extends Component {
trackEvent('ui', 'askToImportModalSeen');
});
}
window.db.getUser(user.uid).then(customUser => {
// storing actual firebase user object for accessing functions like updateProfile
// window.user.firebaseUser = authUser
window.db.getUser(authUser.uid).then(customUser => {
if (customUser) {
const prefs = { ...this.state.prefs };
Object.assign(prefs, user.settings);
const newUser = { ...user, isPro: false, ...customUser };
Object.assign(prefs, authUser.settings);
const newUser = { ...authUser, isPro: false, ...customUser };
window.localStorage.setItem('user', newUser);
this.setState({ user: newUser, prefs }, this.updateSetting);
}
@ -1106,6 +1111,10 @@ export default class App extends Component {
trackEvent('ui', 'openBtnClick');
this.openSavedItemsPane();
}
shareBtnClickHandler() {
trackEvent('ui', 'shareBtnClick');
this.setState({ isShareModalOpen: true });
}
detachedPreviewBtnHandler() {
trackEvent('ui', 'detachPreviewBtnClick');
@ -1641,10 +1650,11 @@ export default class App extends Component {
profileBtnHandler={this.profileBtnClickHandler.bind(this)}
addLibraryBtnHandler={this.openAddLibrary.bind(this)}
assetsBtnHandler={this.assetsBtnClickHandler.bind(this)}
shareBtnHandler={this.shareBtnClickHandler.bind(this)}
runBtnClickHandler={this.runBtnClickHandler.bind(this)}
isFetchingItems={this.state.isFetchingItems}
isSaving={this.state.isSaving}
title={this.state.currentItem.title}
currentItem={this.state.currentItem}
titleInputBlurHandler={this.titleInputBlurHandler.bind(this)}
user={this.state.user}
isAutoPreviewOn={this.state.prefs.autoPreview}
@ -1791,6 +1801,22 @@ export default class App extends Component {
logoutBtnHandler={this.logout.bind(this)}
/>
</Modal>
<Modal
show={this.state.isShareModalOpen}
closeHandler={() => this.setState({ isShareModalOpen: false })}
>
<Share
user={this.state.user}
item={this.state.currentItem}
onVisibilityChange={visibility => {
const item = {
...this.state.currentItem,
isPublic: visibility
};
this.setState({ currentItem: item });
}}
/>
</Modal>
<HelpModal
show={this.state.isHelpModalOpen}
closeHandler={() => this.setState({ isHelpModalOpen: false })}

View File

@ -167,6 +167,18 @@ import { log } from './utils';
return d.promise;
}
async function getPublicItemCount(userId) {
const remoteDb = await getDb();
return remoteDb
.collection('items')
.where('createdBy', '==', userId)
.where('isPublic', '==', true)
.get()
.then(snapShot => {
return snapShot.size;
});
}
window.db = {
getDb,
getUser,
@ -174,6 +186,7 @@ import { log } from './utils';
setUserLastSeenVersion,
getSettings,
fetchItem,
getPublicItemCount,
local: dbLocalAlias,
sync: dbSyncAlias
};

View File

@ -2133,6 +2133,7 @@ while the theme CSS file is loading */
}
.pro-badge {
display: inline-block;
padding: 0.1rem 0.3rem;
background-color: #fff91f;
border-radius: 1rem;