mirror of
https://github.com/filecoin-project/slate.git
synced 2024-11-23 14:07:20 +03:00
slate: back to a stable place
This commit is contained in:
parent
3054b781c3
commit
aa948a60f8
@ -72,6 +72,13 @@ export const getSlateBySlatename = async (data) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const getSlateById = async (data) => {
|
||||
return await returnJSON(`/api/slates/get`, {
|
||||
...DEFAULT_OPTIONS,
|
||||
body: JSON.stringify({ data }),
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteTrustRelationship = async (data) => {
|
||||
return await returnJSON(`/api/users/trust-delete`, {
|
||||
...DEFAULT_OPTIONS,
|
||||
|
@ -44,6 +44,8 @@ import ApplicationLayout from "~/components/core/ApplicationLayout";
|
||||
import WebsitePrototypeWrapper from "~/components/core/WebsitePrototypeWrapper";
|
||||
import Cookies from "universal-cookie";
|
||||
|
||||
import { dispatchCustomEvent } from "~/common/custom-events";
|
||||
|
||||
const cookies = new Cookies();
|
||||
|
||||
const SIDEBARS = {
|
||||
@ -215,6 +217,11 @@ export default class ApplicationPage extends React.Component {
|
||||
|
||||
// NOTE(jim): Rehydrates user.
|
||||
await this.rehydrate({ resetFiles: true });
|
||||
|
||||
dispatchCustomEvent({
|
||||
name: "remote-update-slate-screen",
|
||||
detail: {},
|
||||
});
|
||||
};
|
||||
|
||||
rehydrate = async (options) => {
|
||||
@ -228,7 +235,7 @@ export default class ApplicationPage extends React.Component {
|
||||
console.log("REHYDRATION CALL", response);
|
||||
|
||||
const updates = {
|
||||
viewer: response.data,
|
||||
viewer: JSON.parse(JSON.stringify(response.data)),
|
||||
};
|
||||
|
||||
if (options && options.resetFiles) {
|
||||
@ -269,8 +276,6 @@ export default class ApplicationPage extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
console.log({ response });
|
||||
|
||||
await this.rehydrate();
|
||||
|
||||
this._handleDismissSidebar();
|
||||
|
@ -220,7 +220,6 @@ export default class Slate extends React.Component {
|
||||
return (
|
||||
<div css={STYLES_CONTAINER}>
|
||||
<ResponsiveReactGridLayout
|
||||
className="layout"
|
||||
columns={COLUMN_MAP}
|
||||
layouts={this.props.layouts}
|
||||
isDraggable={!!this.props.editing}
|
||||
@ -235,6 +234,7 @@ export default class Slate extends React.Component {
|
||||
>
|
||||
{this.generateDOM()}
|
||||
</ResponsiveReactGridLayout>
|
||||
|
||||
{this.props.editing ? (
|
||||
<div css={STYLES_ACTIONS}>
|
||||
<span css={STYLES_ACTION_BUTTON} onClick={this._handleResetLayout}>
|
||||
@ -242,7 +242,8 @@ export default class Slate extends React.Component {
|
||||
</span>
|
||||
<span
|
||||
css={STYLES_ACTION_BUTTON}
|
||||
onClick={this._handleSaveLayout}
|
||||
onMouseUp={this._handleSaveLayout}
|
||||
onTouchEnd={this._handleSaveLayout}
|
||||
style={{
|
||||
backgroundColor:
|
||||
this.props.saving === "IDLE" ? Constants.system.brand : null,
|
||||
|
@ -300,9 +300,12 @@ export default class SlateMediaObjectSidebar extends React.Component {
|
||||
|
||||
if (this.props.cid) {
|
||||
elements.push(
|
||||
<div css={STYLES_SIDEBAR} style={{ height: "auto" }}>
|
||||
<div
|
||||
css={STYLES_SIDEBAR}
|
||||
key="sidebar-media-open-file"
|
||||
style={{ height: "auto" }}
|
||||
>
|
||||
<a
|
||||
key="sidebar-media-open-file"
|
||||
css={STYLES_BUTTON}
|
||||
href={Strings.getCIDGatewayURL(this.props.cid)}
|
||||
target="_blank"
|
||||
@ -310,7 +313,6 @@ export default class SlateMediaObjectSidebar extends React.Component {
|
||||
Open file in new tab ⭢
|
||||
</a>
|
||||
<a
|
||||
key="sidebar-media-download-file"
|
||||
css={STYLES_BUTTON}
|
||||
href={Strings.getCIDGatewayURL(this.props.cid)}
|
||||
target="_blank"
|
||||
|
@ -115,6 +115,11 @@ export default class SidebarAddFileToBucket extends React.Component {
|
||||
}
|
||||
|
||||
await this.props.onRehydrate({ resetFiles: true });
|
||||
|
||||
dispatchCustomEvent({
|
||||
name: "remote-update-slate-screen",
|
||||
detail: {},
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
|
@ -12,8 +12,8 @@ export default async ({ id }) => {
|
||||
},
|
||||
errorFn: async (e) => {
|
||||
return {
|
||||
error: "DELETE_TRUSTED_RELATIONSHIP_BY_ID",
|
||||
source: e,
|
||||
decorator: "DELETE_TRUSTED_RELATIONSHIP_BY_ID",
|
||||
error: e,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
@ -1,6 +1,5 @@
|
||||
import * as Utilities from "~/node_common/utilities";
|
||||
import * as Data from "~/node_common/data";
|
||||
import * as Powergate from "~/node_common/powergate";
|
||||
import * as Constants from "~/node_common/constants";
|
||||
import * as Serializers from "~/node_common/serializers";
|
||||
|
||||
|
@ -2,6 +2,23 @@ import * as Data from "~/node_common/data";
|
||||
import * as Utilities from "~/node_common/utilities";
|
||||
import * as Strings from "~/common/strings";
|
||||
|
||||
const generateLayout = (items) => {
|
||||
return items.map((item, i) => {
|
||||
var y = Math.ceil(Math.random() * 4) + 1;
|
||||
|
||||
return {
|
||||
x: (i * 2) % 10,
|
||||
y: 0,
|
||||
w: 2,
|
||||
h: 2,
|
||||
minW: 2,
|
||||
minH: 2,
|
||||
// NOTE(jim): Library quirk thats required.
|
||||
i: i.toString(),
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
export default async (req, res) => {
|
||||
if (Strings.isEmpty(req.body.data.cid)) {
|
||||
return res
|
||||
@ -62,15 +79,16 @@ export default async (req, res) => {
|
||||
const slates = await Data.getSlatesByUserId({ userId: id });
|
||||
for (let i = 0; i < slates.length; i++) {
|
||||
const slate = slates[i];
|
||||
|
||||
await Data.updateSlateById({
|
||||
const objects = slate.data.objects.filter(
|
||||
(o) => !o.url.includes(req.body.data.cid)
|
||||
);
|
||||
const layouts = await Data.updateSlateById({
|
||||
id: slate.id,
|
||||
updated_at: new Date(),
|
||||
data: {
|
||||
...slate.data,
|
||||
objects: slate.data.objects.filter(
|
||||
(o) => !o.url.includes(req.body.data.cid)
|
||||
),
|
||||
objects,
|
||||
layouts: { lg: generateLayout(objects) },
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -2,6 +2,23 @@ import * as Constants from "~/node_common/constants";
|
||||
import * as Utilities from "~/node_common/utilities";
|
||||
import * as Data from "~/node_common/data";
|
||||
|
||||
const generateLayout = (items) => {
|
||||
return items.map((item, i) => {
|
||||
var y = Math.ceil(Math.random() * 4) + 1;
|
||||
|
||||
return {
|
||||
x: (i * 2) % 10,
|
||||
y: 0,
|
||||
w: 2,
|
||||
h: 2,
|
||||
minW: 2,
|
||||
minH: 2,
|
||||
// NOTE(jim): Library quirk thats required.
|
||||
i: i.toString(),
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
export default async (req, res) => {
|
||||
const id = Utilities.getIdFromCookie(req);
|
||||
if (!id) {
|
||||
@ -57,19 +74,8 @@ export default async (req, res) => {
|
||||
},
|
||||
];
|
||||
|
||||
let layouts = slate.data.layouts;
|
||||
if (layouts) {
|
||||
const keys = Object.keys(slate.data.layouts);
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
layouts[keys[i]].push({
|
||||
x: (objects.length * 2) % 10,
|
||||
y: 0,
|
||||
w: 2,
|
||||
h: 2,
|
||||
i: `${objects.length}`.toString(),
|
||||
});
|
||||
}
|
||||
}
|
||||
// TODO(jim): Preserve layouts when adding.
|
||||
let layouts = { lg: generateLayout(objects) };
|
||||
|
||||
const update = await Data.updateSlateById({
|
||||
id: slate.id,
|
||||
|
46
pages/api/slates/get.js
Normal file
46
pages/api/slates/get.js
Normal file
@ -0,0 +1,46 @@
|
||||
import * as Utilities from "~/node_common/utilities";
|
||||
import * as Data from "~/node_common/data";
|
||||
import * as Strings from "~/common/strings";
|
||||
|
||||
export default async (req, res) => {
|
||||
const id = Utilities.getIdFromCookie(req);
|
||||
if (!id) {
|
||||
return res.status(500).send({ decorator: "SERVER_GET_SLATE", error: true });
|
||||
}
|
||||
|
||||
const user = await Data.getUserById({
|
||||
id,
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return res.status(404).send({
|
||||
decorator: "SERVER_GET_SLATE_USER_NOT_FOUND",
|
||||
error: true,
|
||||
});
|
||||
}
|
||||
|
||||
if (user.error) {
|
||||
return res.status(500).send({
|
||||
decorator: "SERVER_GET_SLATE_USER_NOT_FOUND",
|
||||
error: true,
|
||||
});
|
||||
}
|
||||
|
||||
const response = await Data.getSlateById({ id: req.body.data.id });
|
||||
|
||||
if (!response) {
|
||||
return res
|
||||
.status(404)
|
||||
.send({ decorator: "SERVER_GET_SLATE_NOT_FOUND", error: true });
|
||||
}
|
||||
|
||||
if (response.error) {
|
||||
return res
|
||||
.status(500)
|
||||
.send({ decorator: "SERVER_GET_SLATE_NOT_FOUND", error: true });
|
||||
}
|
||||
|
||||
return res
|
||||
.status(200)
|
||||
.send({ decorator: "SERVER_UPDATE_SLATE", slate: response });
|
||||
};
|
@ -4,6 +4,23 @@ import * as LibraryManager from "~/node_common/managers/library";
|
||||
import * as Strings from "~/common/strings";
|
||||
import * as Upload from "~/node_common/upload";
|
||||
|
||||
const generateLayout = (items) => {
|
||||
return items.map((item, i) => {
|
||||
var y = Math.ceil(Math.random() * 4) + 1;
|
||||
|
||||
return {
|
||||
x: (i * 2) % 10,
|
||||
y: 0,
|
||||
w: 2,
|
||||
h: 2,
|
||||
minW: 2,
|
||||
minH: 2,
|
||||
// NOTE(jim): Library quirk thats required.
|
||||
i: i.toString(),
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
// NOTE(jim): To support multipart request.
|
||||
export const config = {
|
||||
api: {
|
||||
@ -121,21 +138,8 @@ export default async (req, res) => {
|
||||
};
|
||||
const objects = [...slate.data.objects, newSlateObjectEntity];
|
||||
|
||||
let layouts = slate.data.layouts;
|
||||
if (layouts) {
|
||||
const keys = Object.keys(slate.data.layouts);
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
layouts[keys[i]].push({
|
||||
x: (objects.length * 2) % 10,
|
||||
y: 0,
|
||||
w: 2,
|
||||
h: 2,
|
||||
minW: 2,
|
||||
minH: 2,
|
||||
i: `${objects.length}`.toString(),
|
||||
});
|
||||
}
|
||||
}
|
||||
// TODO(jim): Preserve layouts when adding.
|
||||
let layouts = { lg: generateLayout(objects) };
|
||||
|
||||
const updatedSlate = await Data.updateSlateById({
|
||||
id: slate.id,
|
||||
|
@ -31,12 +31,7 @@ const moveIndex = (set, fromIndex, toIndex) => {
|
||||
|
||||
const setStateData = (source) => {
|
||||
return {
|
||||
name: source.data.name,
|
||||
username: source.owner ? source.owner.username : null,
|
||||
slatename: source.slatename,
|
||||
public: source.data.public,
|
||||
objects: source.data.objects,
|
||||
body: source.data.body,
|
||||
layouts: source.data.layouts
|
||||
? source.data.layouts
|
||||
: { lg: generateLayout(source.data.objects) },
|
||||
@ -44,6 +39,9 @@ const setStateData = (source) => {
|
||||
};
|
||||
|
||||
export default class SceneSlate extends React.Component {
|
||||
_timeout = null;
|
||||
_remoteLock = false;
|
||||
|
||||
state = {
|
||||
...setStateData(this.props.current, this.props.viewer),
|
||||
loading: false,
|
||||
@ -51,39 +49,61 @@ export default class SceneSlate extends React.Component {
|
||||
editing: this.props.current.data.ownerId === this.props.viewer.id,
|
||||
};
|
||||
|
||||
// NOTE(jim):
|
||||
// The purpose of this is to update the Scene appropriately when
|
||||
// it changes but isn't mounted.
|
||||
componentDidUpdate(prevProps) {
|
||||
if (prevProps.current.id !== this.props.current.id) {
|
||||
this.setState({
|
||||
...setStateData(this.props.current, this.props.viewer),
|
||||
loading: false,
|
||||
saving: "IDLE",
|
||||
editing: this.props.current.data.ownerId === this.props.viewer.id,
|
||||
});
|
||||
|
||||
this._handleUpdateCarousel({
|
||||
objects: this.props.current.data.objects,
|
||||
editing: this.state.editing,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this._handleUpdateCarousel(this.state);
|
||||
window.addEventListener(
|
||||
"remote-update-slate-screen",
|
||||
this._handleRemoteUpdate
|
||||
);
|
||||
}
|
||||
|
||||
// NOTE(jim):
|
||||
// When we are swapping Scenes.
|
||||
componentDidUpdate(prevProps) {
|
||||
const oldDate = prevProps.current.updated_at;
|
||||
const newDate = this.props.current.updated_at;
|
||||
const updated = newDate > oldDate;
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener(
|
||||
"update-current-slate",
|
||||
this._handleRemoteUpdate
|
||||
);
|
||||
}
|
||||
|
||||
if (!updated) {
|
||||
return null;
|
||||
}
|
||||
_handleRemoteUpdate = async ({ detail }) => {
|
||||
if (!this._remoteLock) {
|
||||
this._remoteLock = true;
|
||||
const response = await Actions.getSlateById({
|
||||
id: this.props.current.id,
|
||||
});
|
||||
|
||||
let editing;
|
||||
this.props.viewer.slates.forEach((slate) => {
|
||||
if (slate.id === this.props.current.slateId) {
|
||||
editing = true;
|
||||
if (!response || response.error) {
|
||||
this._remoteLock = false;
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
this.setState({
|
||||
...setStateData(this.props.current, this.props.viewer),
|
||||
loading: false,
|
||||
saving: "SAVED",
|
||||
editing,
|
||||
});
|
||||
this.setState({ layouts: null, objects: null });
|
||||
|
||||
this._handleUpdateCarousel({
|
||||
objects: this.props.current.data.objects,
|
||||
});
|
||||
}
|
||||
const { slate } = response;
|
||||
console.log(slate);
|
||||
|
||||
await this._handleSave(null, slate.data.objects, slate.data.layouts);
|
||||
this._remoteLock = false;
|
||||
}
|
||||
};
|
||||
|
||||
_handleUpdate = async (e) => {
|
||||
let response = await this.props.onRehydrate();
|
||||
@ -110,7 +130,7 @@ export default class SceneSlate extends React.Component {
|
||||
};
|
||||
|
||||
_handleChangeLayout = async (layout, layouts) => {
|
||||
this.setState({ layouts });
|
||||
this.setState({ layouts, saving: "IDLE" });
|
||||
};
|
||||
|
||||
_handleSaveLayout = async () => {
|
||||
@ -124,16 +144,14 @@ export default class SceneSlate extends React.Component {
|
||||
};
|
||||
|
||||
_handleSave = async (e, objects, layouts) => {
|
||||
this.setState({ loading: true });
|
||||
this.setState({ loading: true, saving: "SAVING" });
|
||||
|
||||
const response = await Actions.updateSlate({
|
||||
id: this.props.current.id,
|
||||
data: {
|
||||
name: this.props.current.data.name,
|
||||
objects: objects ? objects : this.state.objects,
|
||||
layouts: layouts ? layouts : this.state.layouts,
|
||||
public: this.state.public,
|
||||
body: this.state.body,
|
||||
name: this.state.name,
|
||||
},
|
||||
});
|
||||
|
||||
@ -149,7 +167,16 @@ export default class SceneSlate extends React.Component {
|
||||
|
||||
await this.props.onRehydrate();
|
||||
|
||||
this._handleUpdateCarousel(this.state);
|
||||
this.setState({
|
||||
saving: "SAVED",
|
||||
layouts: layouts ? layouts : this.state.layouts,
|
||||
objects: objects ? objects : this.state.objects,
|
||||
});
|
||||
|
||||
this._handleUpdateCarousel({
|
||||
objects: objects ? objects : this.state.objects,
|
||||
editing: this.state.editing,
|
||||
});
|
||||
};
|
||||
|
||||
_handleObjectSave = async (object) => {
|
||||
@ -166,8 +193,6 @@ export default class SceneSlate extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
this.setState({ objects });
|
||||
|
||||
await this._handleSave(null, objects);
|
||||
|
||||
System.dispatchCustomEvent({
|
||||
@ -223,24 +248,14 @@ export default class SceneSlate extends React.Component {
|
||||
return o.id !== id;
|
||||
});
|
||||
|
||||
// NOTE(jim): Every time we remove an object from a slate.
|
||||
// We will want to remove the object from the layouts too.
|
||||
const keys = Object.keys(this.state.layouts);
|
||||
let layouts = this.state.layouts;
|
||||
for (let j = 0; j < keys.length; j++) {
|
||||
layouts[keys[j]] = layouts[keys[j]].filter((each, i) => {
|
||||
return i !== index;
|
||||
});
|
||||
}
|
||||
|
||||
// TODO(jim): This is a brute force way to handle this.
|
||||
const layouts = { lg: generateLayout(objects) };
|
||||
const response = await Actions.updateSlate({
|
||||
id: this.props.current.slateId,
|
||||
data: {
|
||||
name: this.props.current.data.name,
|
||||
objects,
|
||||
layouts,
|
||||
public: this.state.public,
|
||||
body: this.state.body,
|
||||
name: this.state.name,
|
||||
},
|
||||
});
|
||||
|
||||
@ -260,9 +275,10 @@ export default class SceneSlate extends React.Component {
|
||||
alert(`TODO: ${response.decorator}`);
|
||||
}
|
||||
|
||||
this._handleUpdateCarousel({ objects, editing: this.state.editing });
|
||||
this.setState({ layouts: null, objects: null });
|
||||
await this.props.onRehydrate();
|
||||
|
||||
this._handleUpdateCarousel(this.state);
|
||||
this.setState({ layouts, objects });
|
||||
|
||||
System.dispatchCustomEvent({
|
||||
name: "state-global-carousel-loading",
|
||||
@ -293,13 +309,9 @@ export default class SceneSlate extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
username,
|
||||
slatename,
|
||||
objects,
|
||||
body = "A slate.",
|
||||
name,
|
||||
} = this.state;
|
||||
const { username, slatename, data, name } = this.props.current;
|
||||
const { body = "A slate." } = data;
|
||||
const { objects, layouts } = this.state;
|
||||
|
||||
return (
|
||||
<ScenePage style={{ padding: `88px 24px 128px 24px` }}>
|
||||
@ -357,17 +369,18 @@ export default class SceneSlate extends React.Component {
|
||||
>
|
||||
<ProcessedText text={body} />
|
||||
</ScenePageHeader>
|
||||
<Slate
|
||||
key={slatename}
|
||||
editing={this.state.editing}
|
||||
saving={this.state.saving}
|
||||
items={objects}
|
||||
layouts={this.state.layouts}
|
||||
onLayoutChange={this._handleChangeLayout}
|
||||
onLayoutSave={this._handleSaveLayout}
|
||||
onMoveIndex={this._handleMoveIndex}
|
||||
onSelect={this._handleSelect}
|
||||
/>
|
||||
{layouts ? (
|
||||
<Slate
|
||||
editing={this.state.editing}
|
||||
saving={this.state.saving}
|
||||
items={objects}
|
||||
layouts={layouts}
|
||||
onLayoutChange={this._handleChangeLayout}
|
||||
onLayoutSave={this._handleSaveLayout}
|
||||
onMoveIndex={this._handleMoveIndex}
|
||||
onSelect={this._handleSelect}
|
||||
/>
|
||||
) : null}
|
||||
</ScenePage>
|
||||
);
|
||||
}
|
||||
|
@ -50,7 +50,9 @@ export default class SceneSlates extends React.Component {
|
||||
const slates = this.props.viewer.slates.map((each) => {
|
||||
return {
|
||||
...each,
|
||||
url: `https://slate.host/${this.props.viewer.username}/${each.slatename}`,
|
||||
url: `https://slate.host/${this.props.viewer.username}/${
|
||||
each.slatename
|
||||
}`,
|
||||
public: each.data.public,
|
||||
objects: <span css={STYLES_NUMBER}>{each.data.objects.length}</span>,
|
||||
};
|
||||
@ -75,11 +77,6 @@ export default class SceneSlates extends React.Component {
|
||||
</div>
|
||||
));
|
||||
|
||||
// TODO(jim): Refactor later.
|
||||
const slateButtons = [
|
||||
{ name: "Create slate", type: "SIDEBAR", value: "SIDEBAR_CREATE_SLATE" },
|
||||
];
|
||||
console.log(this.props);
|
||||
return (
|
||||
<ScenePage>
|
||||
<ScenePageHeader
|
||||
@ -101,8 +98,9 @@ export default class SceneSlates extends React.Component {
|
||||
value={this.state.tab}
|
||||
onChange={(value) => this.setState({ tab: value })}
|
||||
/>
|
||||
|
||||
{this.state.tab === 0 ? (
|
||||
this.props.data.children.length ? (
|
||||
this.props.data && this.props.data.children.length ? (
|
||||
this.props.data.children.map((slate) => (
|
||||
<div
|
||||
key={slate.id}
|
||||
@ -124,6 +122,7 @@ export default class SceneSlates extends React.Component {
|
||||
</EmptyState>
|
||||
)
|
||||
) : null}
|
||||
|
||||
{this.state.tab === 1 ? (
|
||||
subscriptions.length ? (
|
||||
subscriptions
|
||||
|
Loading…
Reference in New Issue
Block a user