Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add movable aa1 to improve basics aa3 #89

Merged
merged 15 commits into from
Jul 8, 2020
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"gh-pages": "^3.1.0",
"js-sha256": "^0.9.0",
"mdbreact": "mdbreact-4.26.1.tgz",
"mdb-react-sortable": "mdb-react-sortable-4.26.0.tgz",
"node-sass": "^4.12.0",
"obelisk.js": "^1.2.2",
"react-avatar-editor": "^11.0.9",
Expand Down
166 changes: 166 additions & 0 deletions src/components/molecules/MovableBoundary/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
//#region > Imports
//> React
// Contains all the functionality necessary to define React components
import React from "react";
// React PropTypes
import PropTypes from "prop-types";
//> MDB Sortable
// MDB plugin for sortable item lists
import MDBSortable from "mdb-react-sortable";

//> CSS
import "./movableboundary.scss";
//#endregion

//#region > Components
/**
* @class This enables implementation of horizontally or vertically movable
* items into a page.
*/
class MovableBoundary extends React.Component {
state = {
items: this.props.items ? this.props.items : null,
indexArray: null,
};

componentWillReceiveProps = (nextProps) => {
this.setState({
items: nextProps.items ? nextProps.items : null,
});

// If props.edit changes to false, save indexArray
if (!nextProps.edit && this.props.edit) {
this.saveItemOrder();
}
};

componentDidMount() {
// Load item order after mounting
this.loadItemOrder();
}

componentDidUpdate(prevProps, prevState) {
// Load items when pool changes
if (prevProps.pool !== this.props.pool) {
this.loadItemOrder();
}
}

/**
* Load the indexArray from storage.
* If there's no indexArray,
* default indexArray [0, 1, 2, 3, ...] will be generated.
*/
loadItemOrder() {
let indexArray = this.props.pool[this.props.uid];

if (!indexArray) {
let baseIndexArray = [];

this.state.items.map((item, i) => {
baseIndexArray = [...baseIndexArray, i];
});

indexArray = baseIndexArray;
} else {
indexArray = JSON.parse(indexArray);
}

this.setState({ indexArray });
}

// Returns items ordered by indexArray
reorderItems() {
let orderedItems = [];

this.state.indexArray.map((index) => {
orderedItems = [...orderedItems, this.state.items[index]];
});

return orderedItems;
}

// Store indexArray
saveItemOrder() {
this.props.pool[this.props.uid] = JSON.stringify(this.state.indexArray);
}

// Returns items to be rendered in the Sortable
renderItems(edit) {
const items = this.reorderItems();

return items.map((item) => {
if (edit) {
return <div className="SortableItem">{item}</div>;
} else {
return (
<div className="SortableItem unsortable" disabled>
{item}
</div>
);
}
});
}

// Swaps indexArray position of element
swap = (newIndex, oldIndex) => {
let indexArray = this.state.indexArray;

if (newIndex >= indexArray.length) {
let k = newIndex - indexArray.length + 1;

while (k--) {
indexArray.push(undefined);
}
}

indexArray.splice(newIndex, 0, indexArray.splice(oldIndex, 1)[0]);

// Save item order when items swap
this.saveItemOrder();
this.setState({ indexArray });
};

render() {
return (
<div>
{this.state.items && this.state.indexArray && (
<>
<MDBSortable
axis={this.props.movementAxis}
items={this.renderItems(this.props.edit ? true : false)}
itemClassName={
this.props.edit ? "SortableItem" : "SortableItem unsortable"
}
listClassName="SortableList"
onSortEnd={(obj, e) => {
// When item is let go of, change indexArray position of item
this.swap(obj.newIndex, obj.oldIndex);
}}
/>
</>
)}
</div>
);
}
}
//#endregion

//#region > PropTypes
MovableBoundary.propTypes = {
pool: PropTypes.object,
movementAxis: PropTypes.string,
items: PropTypes.array.isRequired,
uid: PropTypes.string.isRequired,
edit: PropTypes.bool.isRequired,
};
//#endregion

//#region > Exports
export default MovableBoundary;
//#endregion

/**
* SPDX-License-Identifier: (EUPL-1.2)
* Copyright © 2019-2020 Simon Prast
*/
30 changes: 30 additions & 0 deletions src/components/molecules/MovableBoundary/movableboundary.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
.SortableItem {
list-style: none;
cursor: move;
outline: none;
user-select: text !important;

// View when sorting is enabled
&:not(.unsortable) {
background: transparentize($color: white, $amount: 0.5) !important;
margin-bottom: 1rem;
border-radius: 0.3rem;
padding-top: 0.3rem;
user-select: none !important;
}
}

.SortableList {
display: grid;
grid: initial;
padding: 0;
}

.unsortable {
cursor: default;
}

/**
* SPDX-License-Identifier: (EUPL-1.2)
* Copyright © 2019-2020 Simon Prast
*/
2 changes: 2 additions & 0 deletions src/components/molecules/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import LoginForm from "./forms/LoginForm";
import RegisterForm from "./forms/RegisterForm";
import TalkUploadModal from "./modals/TalkUploadModal";
import UserActionCard from "./UserActionCard";
import MovableBoundary from "./MovableBoundary";
//#endregion

//#region > Exports
Expand All @@ -18,6 +19,7 @@ export {
RegisterForm,
TalkUploadModal,
UserActionCard,
MovableBoundary,
};
//#endregion

Expand Down
8 changes: 8 additions & 0 deletions src/components/organisms/SoftwareTabs/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ class SoftwareTabs extends React.Component {
});
};

isSameOrigin = () => {
const { fetchedUser, loggedUser } = this.props;

return fetchedUser.username === loggedUser.username;
};

render() {
const { fetchedUser } = this.props;
const { activeTab } = this.state;
Expand Down Expand Up @@ -94,6 +100,7 @@ class SoftwareTabs extends React.Component {
{activeTab === 0 && (
<OverviewTab
platformData={fetchedUser && fetchedUser.platformData}
sameOrigin={this.isSameOrigin()}
/>
)}
{activeTab === 1 && (
Expand All @@ -118,6 +125,7 @@ class SoftwareTabs extends React.Component {

//#region > Redux Mapping
const mapStateToProps = (state) => ({
loggedUser: state.auth.loggedUser,
fetchedUser: state.user.fetchedUser,
});

Expand Down
Loading