Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 38 additions & 3 deletions src/components/gui/gui.css
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ $fade-out-distance: 15px;
}

.top-nav-icons{
width: 4.5rem;
width: 7rem;
display: flex;
flex-direction: row;
align-items: center;
Expand All @@ -528,14 +528,49 @@ $fade-out-distance: 15px;
}

.top-nav-icons-left{
width: 4.5rem;
width: 7rem;
display: flex;
flex-direction: row;
align-items: center;
position: absolute;
left: 0;
}

.share-button{
display: flex;
align-items: center;
justify-content: center;
margin-right: 8px;
}

.share-btn{
display: flex;
align-items: center;
justify-content: center;
border: none;
background-color: #fff;
cursor: pointer;
padding: 0;
}

.share-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}

.share-btn img{
background-color: white;
border-radius: 6px;
padding: 7px;
height: 32px;
width: 32px;
}

.share-btn:hover:not(:disabled) img{
background-color: #f5f5f5;
transition: 0.1s ease-in-out;
}

.setting-icon{
width: 1.5rem;
padding-top: 4px;
Expand Down Expand Up @@ -613,4 +648,4 @@ $fade-out-distance: 15px;
}


}
}
33 changes: 27 additions & 6 deletions src/components/gui/gui.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import soundsIcon from './icon--sounds.svg'
import BackArrow from './icon--back-arrow.svg'
import EditAction from './icon--edit-action.svg'
import Cat from './icon--cat.svg'
import ShareIcon from '../menu-bar/share.svg'
import { setSpriteClickedState, addNotification, removeNotification, setProjectName, setPositionModal } from './../../reducers/vm-status.js'
import LanguageMenu from '../menu-bar/language-menu.jsx'
import localforage from 'localforage';
Expand Down Expand Up @@ -145,6 +146,7 @@ const GUIComponent = (props) => {
isPendingState,
projectName,
notifications,
isEditableProject,
...componentProps
} = omit(props, 'dispatch')
if (children) {
Expand Down Expand Up @@ -252,6 +254,12 @@ const GUIComponent = (props) => {
}
}

function handleShare() {
if (remote) {
remote.handleShareClick?.();
}
}


return (
<MediaQuery minWidth={layout.fullSizeMinWidth}>
Expand Down Expand Up @@ -298,28 +306,40 @@ const GUIComponent = (props) => {

<div className={styles.menuBarWithContent}>
{currentLayout === 'myprojects' && <div className={styles.backAndTitle}>
<button disabled={isSaving || isPendingState} onClick={()=>handlebacktomyprojects(remote)} className={styles.backButton}>

<button disabled={isSaving || isPendingState} onClick={()=>handlebacktomyprojects(remote)} className={styles.backButton}>
<img src={BackArrow} />
</button>

<div className={styles.projectnameEdit}>
<div className={styles.catIcon}>
<img src={Cat} />
</div>
<div className={styles.projectnameEdit}>
Scratch - {projectName}
</div>
{ !isEditableProject &&(
<div onClick={() => handleRemoteModal(remote)} className={styles.editIcon}>
<img src={EditAction} />
</div>
)}
</div>
<div className={styles.projectNotifications}>
<NotificationStack notifications={notifications} />
</div>
</div>}
<div className={currentLayout === 'myprojects'? styles.topNavIcons : styles.topNavIconsLeft}>

<div className={currentLayout === 'myprojects'? styles.topNavIcons : styles.topNavIconsLeft}>
<div className={styles.languageRes}>
<LanguageMenu />
</div>
{ !isEditableProject &&(
<div className={styles.shareButton}>
<button disabled={isSaving || isPendingState} onClick={() => handleShare()} className={styles.shareBtn}>
<img src={ShareIcon} />
</button>
</div>
)}
<div className={styles.settingIcon}>
<MenuBarGuiSub
accountNavOpen={accountNavOpen}
Expand Down Expand Up @@ -407,7 +427,7 @@ const GUIComponent = (props) => {
</Tab>
</TabList>}
<TabPanel className={tabClassNames.tabPanel}>
<Box className={styles.blocksWrapper}>
<Box className={styles.blocksWrapper} style={isEditableProject ? { pointerEvents: 'none', opacity: 1 } : {}}>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The opacity: 1 in the inline style is redundant, as it's the default value for opacity. You can safely remove it to make the code a bit cleaner. This also applies to the same pattern on lines 462 and 465.

                    <Box className={styles.blocksWrapper} style={isEditableProject ? { pointerEvents: 'none' } : {}}>

<Blocks
key={`${blocksId}/${theme}`}
canUseCloud={canUseCloud}
Expand Down Expand Up @@ -439,10 +459,10 @@ const GUIComponent = (props) => {
<Watermark />
</Box>
</TabPanel>
<TabPanel className={tabClassNames.tabPanel}>
<TabPanel className={tabClassNames.tabPanel} style={isEditableProject ? { pointerEvents: 'none', opacity: 1 } : {}} >
{costumesTabVisible ? <CostumeTab vm={vm} /> : null}
</TabPanel>
<TabPanel className={tabClassNames.tabPanel}>
<TabPanel className={tabClassNames.tabPanel} style={isEditableProject ? { pointerEvents: 'none', opacity: 1 } : {}}>
{soundsTabVisible ? <SoundTab vm={vm} /> : null}
</TabPanel>
</Tabs>
Expand Down Expand Up @@ -590,6 +610,7 @@ const mapStateToProps = (state) => ({
isSaving: state.scratchGui.vmStatus.isSaving,
isPendingState: state.scratchGui.vmStatus.isPendingState,
projectName: state.scratchGui.vmStatus.projectName,
isEditableProject: state.scratchGui.vmStatus.isEditableProject,
notifications: state.scratchGui.vmStatus.notifications,
})

Expand All @@ -601,4 +622,4 @@ const mapDispatchToProps = {
setPositionModal,
}

export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(GUIComponent))
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(GUIComponent))
8 changes: 4 additions & 4 deletions src/components/menu-bar/menu-bar-gui-sub.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ import {
remixProject,
saveProjectAsCopy,
} from '../../reducers/project-state'
import { setIsLoadingState, setIsFirstState, setIsSavingState, setProjectName, addNotification } from '../../reducers/vm-status.js'
import { setIsLoadingState, setIsFirstState, setIsSavingState, setProjectName, addNotification, setIsEditable } from '../../reducers/vm-status.js'
import {
openAboutMenu,
closeAboutMenu,
Expand Down Expand Up @@ -420,8 +420,8 @@ class MenuBarGuiSub extends React.Component {
const scratchSubstatus = url.get('scratchSubstatus')
const scratchisActivein = url.get('scratchisActivein')
const fetchapiurl = url.get('fetchapiurl')


const isprojecteditable = url.get('editable')
this.props.setIsEditable(isprojecteditable === 'true')
const challengeId = url.get('challengeId')
const chapterId = url.get('chapterId')
const unitId = url.get('unitId')
Expand Down Expand Up @@ -798,7 +798,7 @@ const mapDispatchToProps = (dispatch) => ({
setIsSavingStateFalse: () => dispatch(setIsSavingState(false)),
setProjectName: (name) => dispatch(setProjectName(name)),
addNotification: (notification) => dispatch(addNotification(notification)),

setIsEditable: (isEditable) => dispatch(setIsEditable(isEditable)),
})

export default compose(
Expand Down
3 changes: 3 additions & 0 deletions src/components/menu-bar/share.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion src/containers/sb3-downloader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ class SB3Downloader extends React.Component {
const apiUrl = `${fetchapiurl}/projects/${projectId}`

try {
if(!projectId) {
if(!projectId || this.props.isEditableProject) {
return
}
this.props.setIsSavingState(true)
Expand Down Expand Up @@ -202,6 +202,7 @@ const mapStateToProps = (state) => ({
isFirst: state.scratchGui.vmStatus.isFirst,
projectFilename: getProjectFilename(state.scratchGui.projectTitle, projectTitleInitialState),
projectName: state.scratchGui.vmStatus.projectName,
isEditableProject: state.scratchGui.vmStatus.isEditableProject,
})

const mapDispatchToProps = {
Expand Down
16 changes: 16 additions & 0 deletions src/reducers/vm-status.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ const SET_IS_PENDING_STATE = "scratch-gui/vm-status/SET_IS_PENDING_STATE";
const ADD_NOTIFICATION = "scratch-gui/vm-status/ADD_NOTIFICATION";
const REMOVE_NOTIFICATION = "scratch-gui/vm-status/REMOVE_NOTIFICATION";
const POSITION_MODAL = "scratch-gui/vm-status/POSITION_MODAL";
const SET_ISEDITABLE_PROJECT = "scratch-gui/vm-status/SET_ISEDITABLE_PROJECT";


const initialState = {
running: false,
Expand All @@ -38,6 +40,7 @@ const initialState = {
isPendingState: false,
notifications: [],
positionModal: false,
isEditableProject: true,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The property isEditableProject is named in a way that could be misleading. Based on its usage, when it is true, editing capabilities are disabled. This suggests it functions more like a "read-only" flag.

To improve code clarity and maintainability, I strongly suggest renaming this property to something more descriptive, like isReadOnly or isViewOnly. This would involve inverting the boolean's meaning throughout the application (e.g., isReadOnly: false in the initial state), but it would make the logic much easier to understand at a glance.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This line has a trailing space and a dangling comment (//). Please remove them for code cleanliness.

Suggested change
isEditableProject: true,
isEditableProject: true

};

const reducer = function (state, action) {
Expand Down Expand Up @@ -121,6 +124,11 @@ const reducer = function (state, action) {
(n) => n.id !== action.id
),
};
case SET_ISEDITABLE_PROJECT:
return {
...state,
isEditableProject: action.isEditableProject,
}
default:
return state;
}
Expand Down Expand Up @@ -196,6 +204,13 @@ const setIsLoadingState = function (isLoading) {
};
};

const setIsEditable = function (isEditableProject) {
return {
type: SET_ISEDITABLE_PROJECT,
isEditableProject: isEditableProject,
};
}

const setSpriteClickedState = function (spriteClicked) {
return {
type: SET_SPRITE_CLICKED_STATE,
Expand Down Expand Up @@ -275,4 +290,5 @@ export {
removeNotification,
greenFlagClicked,
setPositionModal,
setIsEditable,
};