links: use componentised metadata

This commit is contained in:
Matilde Park 2020-08-19 21:17:33 -04:00
parent ecfcb55c17
commit 0dbd879443
3 changed files with 27 additions and 184 deletions

View File

@ -93,7 +93,7 @@ export class SettingsScreen extends Component {
association={association} association={association}
resource="chat" resource="chat"
app="chat" app="chat"
station={station} /> />
<Spinner <Spinner
awaiting={this.state.awaiting} awaiting={this.state.awaiting}
classes="absolute right-2 bottom-2 ba pa2 b--gray1-d" classes="absolute right-2 bottom-2 ba pa2 b--gray1-d"

View File

@ -8,39 +8,24 @@ import { Spinner } from '~/views/components/Spinner';
import { LinksTabBar } from './lib/links-tabbar'; import { LinksTabBar } from './lib/links-tabbar';
import SidebarSwitcher from '~/views/components/SidebarSwitch'; import SidebarSwitcher from '~/views/components/SidebarSwitch';
import { MetadataSettings } from '~/views/components/metadata/settings';
export class SettingsScreen extends Component { export class SettingsScreen extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
isLoading: false, isLoading: false,
title: '', awaiting: false,
description: '',
color: '',
disabled: false,
type: 'Editing' type: 'Editing'
}; };
this.changeTitle = this.changeTitle.bind(this);
this.changeDescription = this.changeDescription.bind(this);
this.changeColor = this.changeColor.bind(this);
this.submitColor = this.submitColor.bind(this);
this.renderDelete = this.renderDelete.bind(this); this.renderDelete = this.renderDelete.bind(this);
this.renderMetadataSettings = this.renderMetadataSettings.bind(this);
this.markAllAsSeen = this.markAllAsSeen.bind(this); this.markAllAsSeen = this.markAllAsSeen.bind(this);
this.changeLoading = this.changeLoading.bind(this);
} }
componentDidMount() { componentDidUpdate() {
if ((this.props.resource) && ('metadata' in this.props.resource)) {
this.setState({
title: this.props.resource.metadata.title,
description: this.props.resource.metadata.description,
color: `#${uxToHex(this.props.resource.metadata.color || '0x0')}`
});
}
}
componentDidUpdate(prevProps, prevState) {
const { props, state } = this; const { props, state } = this;
if (Boolean(state.isLoading) && !props.resource) { if (Boolean(state.isLoading) && !props.resource) {
@ -50,64 +35,14 @@ export class SettingsScreen extends Component {
props.history.push('/~link'); props.history.push('/~link');
}); });
} }
}
if (((props.resource) && ('metadata' in props.resource)) changeLoading(isLoading, awaiting, type, closure) {
&& (prevProps !== props)) {
this.setState({ this.setState({
title: props.resource.metadata.title, isLoading,
description: props.resource.metadata.description, awaiting,
color: `#${uxToHex(this.props.resource.metadata.color || '0x0')}` type
}); }, closure);
}
}
changeTitle() {
this.setState({ title: event.target.value });
}
changeDescription() {
this.setState({ description: event.target.value });
}
changeColor() {
this.setState({ color: event.target.value });
}
submitColor() {
const { props, state } = this;
const { resource } = props;
if (!('metadata' in resource)) {
resource.metadata = {};
}
// submit color if valid
let color = state.color;
if (color.startsWith('#')) {
color = state.color.substr(1);
}
const hexExp = /([0-9A-Fa-f]{6})/;
const hexTest = hexExp.exec(color);
let currentColor = '000000';
if (props.resource && 'metadata' in props.resource) {
currentColor = uxToHex(props.resource.metadata.color);
}
if (hexTest && (hexTest[1] !== currentColor)) {
if (props.amOwner) {
this.setState({ disabled: true });
props.api.metadataAdd(
'link',
props.resourcePath,
props.groupPath,
resource.metadata.title,
resource.metadata.description,
resource.metadata['date-created'],
color
).then(() => {
this.setState({ disabled: false });
});
}
}
} }
removeCollection() { removeCollection() {
@ -115,7 +50,7 @@ export class SettingsScreen extends Component {
this.setState({ this.setState({
isLoading: true, isLoading: true,
disabled: true, awaiting: true,
type: 'Removing' type: 'Removing'
}); });
props.api.links.removeCollection(props.resourcePath) props.api.links.removeCollection(props.resourcePath)
@ -131,7 +66,7 @@ export class SettingsScreen extends Component {
this.setState({ this.setState({
isLoading: true, isLoading: true,
disabled: true, awaiting: true,
type: 'Deleting' type: 'Deleting'
}); });
props.api.links.deleteCollection(props.resourcePath) props.api.links.deleteCollection(props.resourcePath)
@ -175,7 +110,7 @@ export class SettingsScreen extends Component {
Delete this collection, for you and all group members. Delete this collection, for you and all group members.
</p> </p>
<a onClick={this.deleteCollection.bind(this)} <a onClick={this.deleteCollection.bind(this)}
className="dib f9 ba pa2 b--red2 red2 pointer bg-gray0-d" className="dib f9 ba pa2 b--red2 red2 pointer bg-gray0-d mb4"
> >
Delete collection Delete collection
</a> </a>
@ -184,105 +119,6 @@ export class SettingsScreen extends Component {
} }
} }
renderMetadataSettings() {
const { props, state } = this;
const { resource } = props;
if (!('metadata' in resource)) {
resource.metadata = {};
}
return(
<div>
<div className={'w-100 pb6 fl mt3 ' + ((props.amOwner) ? '' : 'o-30')}>
<p className="f8 mt3 lh-copy">Rename</p>
<p className="f9 gray2 db mb4">Change the name of this collection</p>
<div className="relative w-100 flex"
style={{ maxWidth: '29rem' }}
>
<input
className={'f8 ba b--gray3 b--gray2-d bg-gray0-d white-d ' +
'focus-b--black focus-b--white-d pa3 db w-100 flex-auto mr3'}
value={this.state.title}
disabled={!props.amOwner || this.state.disabled}
onChange={this.changeTitle}
onBlur={() => {
if (props.amOwner) {
this.setState({ disabled: true });
props.api.metadata.metadataAdd(
'link',
props.resourcePath,
props.groupPath,
state.title,
resource.metadata.description,
resource.metadata['date-created'],
uxToHex(resource.metadata.color)
).then(() => {
this.setState({ disabled: false });
});
}
}}
/>
</div>
<p className="f8 mt3 lh-copy">Change description</p>
<p className="f9 gray2 db mb4">
Change the description of this collection
</p>
<div className="relative w-100 flex"
style={{ maxWidth: '29rem' }}
>
<input
className={'f8 ba b--gray3 b--gray2-d bg-gray0-d white-d ' +
'focus-b--black focus-b--white-d pa3 db w-100 flex-auto mr3'}
value={this.state.description}
disabled={!props.amOwner || this.state.disabled}
onChange={this.changeDescription}
onBlur={() => {
if (props.amOwner) {
this.setState({ disabled: true });
props.api.metadata.metadataAdd(
'link',
props.resourcePath,
props.groupPath,
resource.metadata.title,
state.description,
resource.metadata['date-created'],
uxToHex(resource.metadata.color)
).then(() => {
this.setState({ disabled: false });
});
}
}}
/>
</div>
<p className="f8 mt3 lh-copy">Change color</p>
<p className="f9 gray2 db mb4">Give this collection a color when viewing group channels</p>
<div className="relative w-100 flex"
style={{ maxWidth: '10rem' }}
>
<div className="absolute"
style={{
height: 16,
width: 16,
backgroundColor: state.color,
top: 13,
left: 11
}}
/>
<input
className={'pl7 f8 ba b--gray3 b--gray2-d bg-gray0-d white-d ' +
'focus-b--black focus-b--white-d pa3 db w-100 flex-auto mr3'}
value={this.state.color}
disabled={!props.amOwner || this.state.disabled}
onChange={this.changeColor}
onBlur={this.submitColor}
/>
</div>
</div>
</div>
);
}
render() { render() {
const { props, state } = this; const { props, state } = this;
@ -367,11 +203,18 @@ export class SettingsScreen extends Component {
</a> </a>
{this.renderRemove()} {this.renderRemove()}
{this.renderDelete()} {this.renderDelete()}
{this.renderMetadataSettings()} <MetadataSettings
isOwner={props.amOwner}
changeLoading={this.changeLoading}
api={props.api}
association={props.resource}
resource="collection"
app="link"
/>
<Spinner <Spinner
awaiting={this.state.disabled} awaiting={this.state.awaiting}
classes="absolute right-1 bottom-1 pa2 ba b--black b--gray0-d white-d" classes="absolute right-1 bottom-1 pa2 ba b--black b--gray0-d white-d"
text={`${this.state.type} collection...`} text={this.state.type}
/> />
</div> </div>
</div> </div>

View File

@ -1,4 +1,4 @@
import React, { Component } from 'react'; import React from 'react';
import { MetadataColor } from './color'; import { MetadataColor } from './color';
import { MetadataInput } from './input'; import { MetadataInput } from './input';
@ -53,7 +53,7 @@ export const MetadataSettings = (props) => {
isDisabled={!isOwner} isDisabled={!isOwner}
initialValue={description} initialValue={description}
setValue={(val) => { setValue={(val) => {
changeLoading(false, true, 'Editing chat...', () => { changeLoading(false, true, `Editing ${resource}...`, () => {
api.metadata.metadataAdd( api.metadata.metadataAdd(
app, app,
association['app-path'], association['app-path'],