slate: cleans up state, guarantees JSON response from endpoints, updates server code

This commit is contained in:
@wwwjim 2020-08-24 23:46:02 -07:00
parent d346919a3f
commit 5542f76888
13 changed files with 112 additions and 61 deletions

View File

@ -53,7 +53,7 @@ export const getSelectedState = (props) => {
return { return {
address: null, address: null,
// address: info.defaultStorageConfig.cold.filecoin.addr, address: info.defaultStorageConfig.cold.filecoin.addr,
}; };
}; };
@ -62,6 +62,14 @@ export const getInitialState = (props) => {
return null; return null;
} }
return { ...props };
};
export const _deprecated_getInitialState = (props) => {
if (!props) {
return null;
}
const { const {
id, id,
status, status,
@ -89,20 +97,28 @@ export const getInitialState = (props) => {
settings_deals_auto_approve: settings.deals_auto_approve, settings_deals_auto_approve: settings.deals_auto_approve,
// NOTE(jim): Powergate Hot Settings // NOTE(jim): Powergate Hot Settings
// settings_hot_enabled: info.defaultStorageConfig.hot.enabled, settings_hot_enabled: info.defaultStorageConfig.hot.enabled,
// settings_hot_allow_unfreeze: info.defaultStorageConfig.hot.allowUnfreeze, settings_hot_allow_unfreeze: info.defaultStorageConfig.hot.allowUnfreeze,
// settings_hot_ipfs_add_timeout: info.defaultStorageConfig.hot.ipfs.addTimeout, settings_hot_ipfs_add_timeout:
info.defaultStorageConfig.hot.ipfs.addTimeout,
// NOTE(jim): Powergate Cold Settings // NOTE(jim): Powergate Cold Settings
// settings_cold_enabled: info.defaultStorageConfig.cold.enabled, settings_cold_enabled: info.defaultStorageConfig.cold.enabled,
// settings_cold_default_address: info.defaultStorageConfig.cold.filecoin.addr, settings_cold_default_address: info.defaultStorageConfig.cold.filecoin.addr,
// settings_cold_default_duration: info.defaultStorageConfig.cold.filecoin.dealMinDuration, settings_cold_default_duration:
// settings_cold_default_replication_factor: info.defaultStorageConfig.cold.filecoin.repFactor, info.defaultStorageConfig.cold.filecoin.dealMinDuration,
// settings_cold_default_excluded_miners: info.defaultStorageConfig.cold.filecoin.excludedMinersList, settings_cold_default_replication_factor:
// settings_cold_default_trusted_miners: info.defaultStorageConfig.cold.filecoin.trustedMinersList, info.defaultStorageConfig.cold.filecoin.repFactor,
// settings_cold_default_max_price: info.defaultStorageConfig.cold.filecoin.maxPrice, settings_cold_default_excluded_miners:
// settings_cold_default_auto_renew: info.defaultStorageConfig.cold.filecoin.renew.enabled, info.defaultStorageConfig.cold.filecoin.excludedMinersList,
// settings_cold_default_auto_renew_max_price: info.defaultStorageConfig.cold.filecoin.renew.threshold, settings_cold_default_trusted_miners:
info.defaultStorageConfig.cold.filecoin.trustedMinersList,
settings_cold_default_max_price:
info.defaultStorageConfig.cold.filecoin.maxPrice,
settings_cold_default_auto_renew:
info.defaultStorageConfig.cold.filecoin.renew.enabled,
settings_cold_default_auto_renew_max_price:
info.defaultStorageConfig.cold.filecoin.renew.threshold,
storageList, storageList,
retrievalList, retrievalList,
@ -110,7 +126,7 @@ export const getInitialState = (props) => {
keys, keys,
stats, stats,
library, library,
// peers: transformPeers(peersList), peers: transformPeers(peersList),
// addresses: transformAddresses(addrsList, info), addresses: transformAddresses(addrsList, info),
}; };
}; };

View File

@ -72,8 +72,8 @@ const SCENES = {
export default class ApplicationPage extends React.Component { export default class ApplicationPage extends React.Component {
state = { state = {
selected: State.getSelectedState(this.props.viewer), selected: {},
viewer: State.getInitialState(this.props.viewer), viewer: this.props.viewer,
history: [{ id: "V1_NAVIGATION_HOME", scrollTop: 0, data: null }], history: [{ id: "V1_NAVIGATION_HOME", scrollTop: 0, data: null }],
currentIndex: 0, currentIndex: 0,
data: null, data: null,
@ -120,7 +120,11 @@ export default class ApplicationPage extends React.Component {
} }
// NOTE(jim): Only allow the sidebar to show with file drag and drop. // NOTE(jim): Only allow the sidebar to show with file drag and drop.
if (e.dataTransfer.items && e.dataTransfer.items.length && e.dataTransfer.items[0].kind !== "file") { if (
e.dataTransfer.items &&
e.dataTransfer.items.length &&
e.dataTransfer.items[0].kind !== "file"
) {
return; return;
} }
@ -274,7 +278,8 @@ export default class ApplicationPage extends React.Component {
_handleDeleteYourself = async () => { _handleDeleteYourself = async () => {
// TODO(jim): // TODO(jim):
// Put this somewhere better for messages. // Put this somewhere better for messages.
const message = "Do you really want to delete your account? It will be permanently removed"; const message =
"Do you really want to delete your account? It will be permanently removed";
if (!window.confirm(message)) { if (!window.confirm(message)) {
return false; return false;
} }
@ -445,8 +450,12 @@ export default class ApplicationPage extends React.Component {
<WebsitePrototypeWrapper <WebsitePrototypeWrapper
title="Slate: sign in" title="Slate: sign in"
description="Sign in to your Slate account to manage your assets." description="Sign in to your Slate account to manage your assets."
url="https://slate.host/_"> url="https://slate.host/_"
<SceneSignIn onAuthenticate={this._handleAuthenticate} onNavigateTo={this._handleNavigateTo} /> >
<SceneSignIn
onAuthenticate={this._handleAuthenticate}
onNavigateTo={this._handleNavigateTo}
/>
</WebsitePrototypeWrapper> </WebsitePrototypeWrapper>
); );
} }
@ -519,12 +528,17 @@ export default class ApplicationPage extends React.Component {
return ( return (
<React.Fragment> <React.Fragment>
<WebsitePrototypeWrapper description={description} title={title} url={url}> <WebsitePrototypeWrapper
description={description}
title={title}
url={url}
>
<ApplicationLayout <ApplicationLayout
header={headerElement} header={headerElement}
navigation={navigationElement} navigation={navigationElement}
sidebar={sidebarElement} sidebar={sidebarElement}
onDismissSidebar={this._handleDismissSidebar}> onDismissSidebar={this._handleDismissSidebar}
>
{scene} {scene}
</ApplicationLayout> </ApplicationLayout>
<System.GlobalCarousel /> <System.GlobalCarousel />

View File

@ -4,14 +4,17 @@ export default async ({ key }) => {
return await runQuery({ return await runQuery({
label: "GET_API_KEY_BY_KEY", label: "GET_API_KEY_BY_KEY",
queryFn: async (DB) => { queryFn: async (DB) => {
const query = await DB.select("*").from("keys").where({ key }).first(); const query = await DB.select("*")
.from("keys")
.where({ key })
.first();
if (!query || query.error) { if (!query || query.error) {
return null; return null;
} }
if (query.id) { if (query.id) {
return query; return JSON.parse(JSON.stringify(query));
} }
return null; return null;

View File

@ -14,7 +14,7 @@ export default async ({ id }) => {
} }
if (query.id) { if (query.id) {
return query; return JSON.parse(JSON.stringify(query));
} }
return null; return null;

View File

@ -12,7 +12,7 @@ export default async ({ userId }) => {
return []; return [];
} }
return query; return JSON.parse(JSON.stringify(query));
}, },
errorFn: async (e) => { errorFn: async (e) => {
return { return {

View File

@ -14,7 +14,7 @@ export default async ({ id }) => {
} }
if (query.id) { if (query.id) {
return query; return JSON.parse(JSON.stringify(query));
} }
return null; return null;

View File

@ -14,7 +14,7 @@ export default async ({ slatename }) => {
} }
if (query.id) { if (query.id) {
return query; return JSON.parse(JSON.stringify(query));
} }
return null; return null;

View File

@ -4,21 +4,28 @@ export default async ({ userId, publicOnly = false }) => {
return await runQuery({ return await runQuery({
label: "GET_SLATES_BY_USER_ID", label: "GET_SLATES_BY_USER_ID",
queryFn: async (DB) => { queryFn: async (DB) => {
const hasUser = (id) => DB.raw(`?? @> ?::jsonb`, ["data", JSON.stringify({ ownerId: id })]); const hasUser = (id) =>
const isPublic = () => DB.raw(`?? @> ?::jsonb`, ["data", JSON.stringify({ public: true })]); DB.raw(`?? @> ?::jsonb`, ["data", JSON.stringify({ ownerId: id })]);
const isPublic = () =>
DB.raw(`?? @> ?::jsonb`, ["data", JSON.stringify({ public: true })]);
let query; let query;
if (publicOnly) { if (publicOnly) {
query = await DB.select("*").from("slates").where(hasUser(userId)).where(isPublic()); query = await DB.select("*")
.from("slates")
.where(hasUser(userId))
.where(isPublic());
} else { } else {
query = await DB.select("*").from("slates").where(hasUser(userId)); query = await DB.select("*")
.from("slates")
.where(hasUser(userId));
} }
if (!query || query.error) { if (!query || query.error) {
return []; return [];
} }
return query; return JSON.parse(JSON.stringify(query));
}, },
errorFn: async (e) => { errorFn: async (e) => {
return { return {

View File

@ -14,7 +14,7 @@ export default async ({ id }) => {
} }
if (query.id) { if (query.id) {
return query; return JSON.parse(JSON.stringify(query));
} }
return null; return null;

View File

@ -14,7 +14,7 @@ export default async ({ username }) => {
} }
if (query.id) { if (query.id) {
return query; return JSON.parse(JSON.stringify(query));
} }
return null; return null;

View File

@ -17,11 +17,8 @@ export const getById = async ({ id }) => {
} }
let data = null; let data = null;
const response = await Data.getSlatesByUserId({ userId: id }); const slates = await Data.getSlatesByUserId({ userId: id });
const slates = JSON.parse(JSON.stringify(response)); const keys = await Data.getAPIKeysByUserId({ userId: id });
const keysRaw = await Data.getAPIKeysByUserId({ userId: id });
const keys = JSON.parse(JSON.stringify(keysRaw));
let bytes = 0; let bytes = 0;
user.data.library[0].children.forEach((each) => { user.data.library[0].children.forEach((each) => {
@ -54,17 +51,6 @@ export const getById = async ({ id }) => {
addrsList: null, addrsList: null,
info: null, info: null,
}; };
// TODO(jim): Disables Powergate Features
/*
const updates = await Utilities.refresh(user);
const updatesWithToken = await Utilities.refreshWithToken(user);
data = await Utilities.updateStateData(data, {
...updates,
...updatesWithToken,
});
*/
} catch (e) { } catch (e) {
console.log(e); console.log(e);
return null; return null;

View File

@ -98,7 +98,9 @@ export default class SlatePage extends React.Component {
return { return {
id: each.id, id: each.id,
data: each, data: each,
component: <SlateMediaObject key={each.id} useImageFallback data={each} />, component: (
<SlateMediaObject key={each.id} useImageFallback data={each} />
),
}; };
}), }),
}, },
@ -112,8 +114,10 @@ export default class SlatePage extends React.Component {
}); });
render() { render() {
const title = `${this.props.slate.ownername}/${this.props.slate.slatename}`; const title = `${this.props.creator.username}/${
const url = `https://slate.host/${this.props.slate.ownername}`; this.props.slate.slatename
}`;
const url = `https://slate.host/${this.props.creator.username}`;
const description = this.props.slate.data.body; const description = this.props.slate.data.body;
let image; let image;
@ -124,12 +128,17 @@ export default class SlatePage extends React.Component {
}); });
return ( return (
<WebsitePrototypeWrapper title={title} description={description} url={url} image={image}> <WebsitePrototypeWrapper
title={title}
description={description}
url={url}
image={image}
>
<div css={STYLES_ROOT}> <div css={STYLES_ROOT}>
<WebsitePrototypeHeaderGeneric href={url}> <WebsitePrototypeHeaderGeneric href={url}>
<div css={STYLES_HEADER}> <div css={STYLES_HEADER}>
<div css={STYLES_HEADER_LEFT}> <div css={STYLES_HEADER_LEFT}>
{this.props.slate.ownername} / {this.props.slate.slatename} {this.props.creator.username} / {this.props.slate.slatename}
</div> </div>
<div css={STYLES_HEADER_RIGHT}>{this.props.slate.data.body}</div> <div css={STYLES_HEADER_RIGHT}>{this.props.slate.data.body}</div>
</div> </div>

View File

@ -106,12 +106,12 @@ app.prepare().then(async () => {
viewer, viewer,
creator: { creator: {
username: creator.username, username: creator.username,
slates,
data: { data: {
photo: creator.data.photo, photo: creator.data.photo,
name: creator.data.name ? creator.data.name : creator.username, name: creator.data.name ? creator.data.name : creator.username,
body: creator.data.body ? creator.data.body : "A user on Slate.", body: creator.data.body ? creator.data.body : "A user on Slate.",
}, },
slates: JSON.parse(JSON.stringify(slates)),
}, },
}); });
}); });
@ -148,10 +148,26 @@ app.prepare().then(async () => {
return res.redirect("/403"); return res.redirect("/403");
} }
const id = Utilities.getIdFromCookie(req);
let viewer = null;
if (id) {
viewer = await ViewerManager.getById({
id,
});
}
return app.render(req, res, "/_/slate", { return app.render(req, res, "/_/slate", {
slate: JSON.parse( viewer,
JSON.stringify({ ...slate, ownername: req.params.username }) creator: {
), username: creator.username,
data: {
photo: creator.data.photo,
name: creator.data.name ? creator.data.name : creator.username,
body: creator.data.body ? creator.data.body : "A user on Slate.",
},
},
slate,
}); });
}); });