mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-11-13 08:38:43 +03:00
spa: intra-navigation uses react-router
This commit is contained in:
parent
056cd51478
commit
b720a6994b
@ -1,239 +0,0 @@
|
||||
import React, { Component } from 'react';
|
||||
|
||||
export class GroupFilter extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
open: false,
|
||||
selected: [],
|
||||
groups: [],
|
||||
searchTerm: '',
|
||||
results: []
|
||||
};
|
||||
this.toggleOpen = this.toggleOpen.bind(this);
|
||||
this.handleClickOutside = this.handleClickOutside.bind(this);
|
||||
this.groupIndex = this.groupIndex.bind(this);
|
||||
this.search = this.search.bind(this);
|
||||
this.addGroup = this.addGroup.bind(this);
|
||||
this.deleteGroup = this.deleteGroup.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
document.addEventListener('mousedown', this.handleClickOutside);
|
||||
this.groupIndex();
|
||||
const selected = localStorage.getItem('urbit-selectedGroups');
|
||||
if (selected) {
|
||||
this.setState({ selected: JSON.parse(selected) }, (() => {
|
||||
window.api.setSelected(this.state.selected);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
document.removeEventListener('mousedown', this.handleClickOutside);
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (prevProps !== this.props) {
|
||||
this.groupIndex();
|
||||
}
|
||||
}
|
||||
|
||||
handleClickOutside(evt) {
|
||||
if ((this.dropdown && !this.dropdown.contains(evt.target))
|
||||
&& (this.toggleButton && !this.toggleButton.contains(evt.target))) {
|
||||
this.setState({ open: false });
|
||||
}
|
||||
}
|
||||
|
||||
toggleOpen() {
|
||||
this.setState({ open: !this.state.open });
|
||||
}
|
||||
|
||||
groupIndex() {
|
||||
const { props } = this;
|
||||
let index = [];
|
||||
const associations = props.associations ? props.associations.contacts : {};
|
||||
index = Object.keys(associations).map((each) => {
|
||||
const eachGroup = [];
|
||||
eachGroup.push(each);
|
||||
let name = each;
|
||||
if (associations[each].metadata) {
|
||||
name = (associations[each].metadata.title !== '')
|
||||
? associations[each].metadata.title : name;
|
||||
}
|
||||
eachGroup.push(name);
|
||||
return eachGroup;
|
||||
});
|
||||
this.setState({ groups: index });
|
||||
}
|
||||
|
||||
search(evt) {
|
||||
this.setState({ searchTerm: evt.target.value });
|
||||
const term = evt.target.value.toLowerCase();
|
||||
|
||||
if (term.length < 3) {
|
||||
return this.setState({ results: [] });
|
||||
}
|
||||
|
||||
let groupMatches = [];
|
||||
groupMatches = this.state.groups.filter((e) => {
|
||||
return (e[0].includes(term) || e[1].includes(term));
|
||||
});
|
||||
this.setState({ results: groupMatches });
|
||||
}
|
||||
|
||||
addGroup(group) {
|
||||
const selected = this.state.selected;
|
||||
if (!(group in selected)) {
|
||||
selected.push(group);
|
||||
}
|
||||
this.setState({
|
||||
searchTerm: '',
|
||||
selected: selected,
|
||||
results: []
|
||||
}, (() => {
|
||||
window.api.setSelected(this.state.selected);
|
||||
localStorage.setItem('urbit-selectedGroups', JSON.stringify(this.state.selected));
|
||||
}));
|
||||
}
|
||||
|
||||
deleteGroup(group) {
|
||||
let selected = this.state.selected;
|
||||
selected = selected.filter((e) => {
|
||||
return e !== group;
|
||||
});
|
||||
this.setState({ selected: selected }, (() => {
|
||||
window.api.setSelected(this.state.selected);
|
||||
localStorage.setItem('urbit-selectedGroups', JSON.stringify(this.state.selected));
|
||||
}));
|
||||
}
|
||||
|
||||
render() {
|
||||
const { props, state } = this;
|
||||
|
||||
let currentGroup = 'All Groups';
|
||||
|
||||
if (state.selected.length > 0) {
|
||||
const titles = state.selected.map((each) => {
|
||||
return each[1];
|
||||
});
|
||||
currentGroup = titles.join(' + ');
|
||||
}
|
||||
|
||||
const buttonOpened = (state.open)
|
||||
? 'bg-gray5 bg-gray1-d white-d' : 'hover-bg-gray5 hover-bg-gray1-d white-d';
|
||||
|
||||
const dropdownClass = (state.open)
|
||||
? 'absolute db z-2 bg-white bg-gray0-d white-d ba b--gray3 b--gray1-d'
|
||||
: 'dn';
|
||||
|
||||
const inviteCount = (props.invites && Object.keys(props.invites).length > 0)
|
||||
? <template className="dib fr">
|
||||
<p className="dib bg-green2 bg-gray2-d white fw6 ph1 br1 v-mid" style={{ marginBottom: 2 }}>
|
||||
{Object.keys(props.invites).length}
|
||||
</p>
|
||||
<span className="dib v-mid ml1">
|
||||
<img
|
||||
className="v-mid"
|
||||
src="/~landscape/img/Chevron.png"
|
||||
style={{ height: 16, width: 16, paddingBottom: 1 }}
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
: <template className="dib fr">
|
||||
<span className="dib v-top ml1">
|
||||
<img className="v-mid"
|
||||
src="/~landscape/img/Chevron.png"
|
||||
style={{ height: 16, width: 16, paddingBottom: 1 }}
|
||||
/>
|
||||
</span>
|
||||
</template>;
|
||||
|
||||
let selectedGroups = <div />;
|
||||
let searchResults = <div />;
|
||||
|
||||
if (state.results.length > 0) {
|
||||
const groupResults = state.results.map(((group) => {
|
||||
return(
|
||||
<li
|
||||
key={group[0]}
|
||||
className="tl list white-d f9 pv2 ph3 pointer hover-bg-gray4 hover-bg-gray1-d inter" onClick={() => this.addGroup(group)}
|
||||
>
|
||||
<span className="mix-blend-diff white">{(group[1]) ? group[1] : group[0]}</span>
|
||||
</li>
|
||||
);
|
||||
}));
|
||||
searchResults = (
|
||||
<div className={'tl absolute bg-white bg-gray0-d white-d pv3 z-1 w-100 ba b--gray4 b--white-d overflow-y-scroll'} style={{ maxWidth: '15.67rem', maxHeight: '8rem' }}>
|
||||
<p className="f9 tl gray2 ph3 pb2">Groups</p>
|
||||
{groupResults}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (state.selected.length > 0) {
|
||||
const allSelected = this.state.selected.map((each) => {
|
||||
const name = each[1];
|
||||
return(
|
||||
<span
|
||||
key={each[0]}
|
||||
className={'f9 inter black pa2 bg-gray5 bg-gray1-d ' +
|
||||
'ba b--gray4 b--gray2-d white-d dib mr2 mt2 c-default'}
|
||||
>
|
||||
{name}
|
||||
<span
|
||||
className="white-d ml3 mono pointer"
|
||||
onClick={e => this.deleteGroup(each)}
|
||||
>
|
||||
x
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
});
|
||||
selectedGroups = (
|
||||
<div className={
|
||||
'f9 gray2 bb bl br b--gray3 b--gray2-d bg-gray0-d ' +
|
||||
'white-d pa3 db w-100 inter bg-gray5 lh-solid tl'
|
||||
} style={{ width: 251 }}
|
||||
>
|
||||
{allSelected}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="ml1 dib">
|
||||
<div className={buttonOpened}
|
||||
onClick={() => this.toggleOpen()}
|
||||
ref={el => this.toggleButton = el}
|
||||
>
|
||||
<p className="dib f9 pointer pv1 ph2 mw5 truncate v-mid">{currentGroup}</p>
|
||||
</div>
|
||||
<div className={dropdownClass}
|
||||
style={{ maxHeight: '24rem', width: 285 }}
|
||||
ref={(el) => {
|
||||
this.dropdown = el;
|
||||
}}
|
||||
>
|
||||
<p className="tc bb b--gray3 b--gray1-d gray3 pv4 f9">Group Select and Filter</p>
|
||||
<a href="/~groups" className="ma4 bg-gray5 bg-gray1-d f9 tl pa1 br1 db no-underline" style={{ paddingLeft: '6.5px', paddingRight: '6.5px' }}>Manage all Groups
|
||||
{inviteCount}
|
||||
</a>
|
||||
<p className="pt4 gray3 f9 tl mh4">Filter Groups</p>
|
||||
<div className="relative w-100 ph4 pt2 pb4">
|
||||
<input className="ba b--gray3 white-d bg-gray0-d inter w-100 f9 pa2" style={{ boxSizing: 'border-box' }}
|
||||
placeholder="Group name..."
|
||||
onChange={this.search}
|
||||
value={state.searchTerm}
|
||||
/>
|
||||
{searchResults}
|
||||
{selectedGroups}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default GroupFilter;
|
@ -87,12 +87,12 @@ export class ProfileOverlay extends Component {
|
||||
</Link>
|
||||
)}
|
||||
{isOwn && (
|
||||
<a
|
||||
href={identityHref}
|
||||
<Link
|
||||
to={identityHref}
|
||||
className="b--black b--white-d ba black white-d mt3 tc pa2 pointer db"
|
||||
>
|
||||
Edit Group Identity
|
||||
</a>
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,5 +1,6 @@
|
||||
import React, { Component } from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
export class Skeleton extends Component {
|
||||
render() {
|
||||
@ -48,9 +49,9 @@ export class Skeleton extends Component {
|
||||
>
|
||||
{/* mobile-specific navigation */}
|
||||
<div className={mobileNavClasses}>
|
||||
<a className="pl3 pb6" href="/">
|
||||
<Link className="pl3 pb6" to="/">
|
||||
{'⟵ Landscape'}
|
||||
</a>
|
||||
</Link>
|
||||
<div className="bb b--gray4 b--gray1-d white-d inter f8 pl3 pt6 pb3">
|
||||
All Chats
|
||||
</div>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Route } from 'react-router-dom';
|
||||
import { Route, Link } from 'react-router-dom';
|
||||
import classnames from 'classnames';
|
||||
|
||||
import { Popout } from './components/lib/icons/popout';
|
||||
@ -68,9 +68,9 @@ export default class DojoApp extends Component {
|
||||
className="db dn-m dn-l dn-xl inter bg-white bg-gray0-d dt w-100"
|
||||
style={{ height: 40 }}
|
||||
>
|
||||
<a className="f8 pl3 black white-d dtc h-100 v-mid" href="/">
|
||||
<Link className="f8 pl3 black white-d dtc h-100 v-mid" to="/">
|
||||
⟵ Landscape
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
<div
|
||||
className={
|
||||
|
@ -117,9 +117,9 @@ export class GroupDetail extends Component {
|
||||
<p className="f9 inter ml2 w-100">{title}</p>
|
||||
<p className="f9 inter ml2 w-100">
|
||||
<span className="f9 di mr2 inter">{app}</span>
|
||||
<a className="f9 di green2" href={link}>
|
||||
<Link className="f9 di green2" to={link}>
|
||||
Open
|
||||
</a>
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
|
@ -135,7 +135,7 @@ export class GroupSidebar extends Component {
|
||||
'flex-basis-30-ns flex-shrink-0 mw5-m mw5-l mw5-xl flex-basis-100-s ' +
|
||||
'relative overflow-hidden pt3 pt0-m pt0-l pt0-xl ' + activeClasses}
|
||||
>
|
||||
<a className="db dn-m dn-l dn-xl f8 pb6 pl3" href="/">⟵ Landscape</a>
|
||||
<Link className="db dn-m dn-l dn-xl f8 pb6 pl3" to="/">⟵ Landscape</Link>
|
||||
<div className="overflow-auto pb8 h-100">
|
||||
<Link to="/~groups/new" className="dib">
|
||||
<p className="f9 pt4 pl4 green2 bn">Create Group</p>
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React from 'react'
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
export default class Welcome extends React.Component {
|
||||
constructor() {
|
||||
@ -17,13 +18,13 @@ export default class Welcome extends React.Component {
|
||||
render() {
|
||||
let firstTime = this.props.firstTime;
|
||||
return (firstTime && this.state.show) ? (
|
||||
<div className={"fl ma2 bg-white bg-gray0-d white-d overflow-hidden " +
|
||||
"ba b--black b--gray1-d pa2 lh-copy"}>
|
||||
<div className={'fl ma2 bg-white bg-gray0-d white-d overflow-hidden ' +
|
||||
'ba b--black b--gray1-d pa2 lh-copy'}>
|
||||
<p className="f9">Welcome. This virtual computer belongs to you completely. The Urbit ID you used to boot it is yours as well.</p>
|
||||
<p className="f9 pt2">Since your ID and OS belong to you, it’s up to you to keep them safe. Be sure your ID is somewhere you won’t lose it and you keep your OS on a machine you trust.</p>
|
||||
<p className="f9 pt2">Urbit OS is designed to keep your data secure and hard to lose. But the system is still young — so don’t put anything critical in here just yet.</p>
|
||||
<p className="f9 pt2">To begin exploring, you should probably pop into a chat and verify there are signs of life in this new place. If you were invited by a friend, you probably already have access to a few groups.</p>
|
||||
<p className="f9 pt2">If you don't know where to go, feel free to <a className="no-underline bb b--black b--gray1-d dib" href="/~chat/join/~/~dopzod/urbit-help">join our lobby.</a>
|
||||
<p className="f9 pt2">If you don't know where to go, feel free to <Link className="no-underline bb b--black b--gray1-d dib" to="/~chat/join/~/~dopzod/urbit-help">join our lobby.</Link>
|
||||
</p>
|
||||
<p className="f9 pt2">Have fun!</p>
|
||||
<p className="dib f9 pt2 bb b--black b--gray1-d pointer"
|
||||
|
@ -115,7 +115,7 @@ export class ChannelsSidebar extends Component {
|
||||
? 'flex-basis-100-s flex-basis-30-ns'
|
||||
: 'dn')}
|
||||
>
|
||||
<a className="db dn-m dn-l dn-xl f8 pb3 pl3" href="/">⟵ Landscape</a>
|
||||
<Link className="db dn-m dn-l dn-xl f8 pb3 pl3" to="/">⟵ Landscape</Link>
|
||||
<div className="overflow-y-scroll h-100">
|
||||
<div className="w-100 bg-transparent">
|
||||
<Link
|
||||
|
@ -118,9 +118,9 @@ export class Sidebar extends Component {
|
||||
(hiddenClasses ? 'flex-basis-100-s flex-basis-250-ns' : 'dn')
|
||||
}
|
||||
>
|
||||
<a className="db dn-m dn-l dn-xl f9 pb3 pl3" href="/">
|
||||
<Link className="db dn-m dn-l dn-xl f9 pb3 pl3" to="/">
|
||||
⟵ Landscape
|
||||
</a>
|
||||
</Link>
|
||||
<div className="w-100 f9">
|
||||
<Link to="/~publish/new" className="green2 pa4 f9 dib">
|
||||
New Notebook
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
export default class GroupFilter extends Component {
|
||||
constructor(props) {
|
||||
@ -219,9 +220,9 @@ onClick={() => this.addGroup(group)}
|
||||
}}
|
||||
>
|
||||
<p className="tc bb b--gray3 b--gray1-d gray3 pv4 f9">Group Select and Filter</p>
|
||||
<a href="/~groups" className="ma4 bg-gray5 bg-gray1-d f9 tl pa1 br1 db no-underline" style={{ paddingLeft: '6.5px', paddingRight: '6.5px' }}>Manage all Groups
|
||||
<Link to="/~groups" className="ma4 bg-gray5 bg-gray1-d f9 tl pa1 br1 db no-underline" style={{ paddingLeft: '6.5px', paddingRight: '6.5px' }}>Manage all Groups
|
||||
{inviteCount}
|
||||
</a>
|
||||
</Link>
|
||||
<p className="pt4 gray3 f9 tl mh4">Filter Groups</p>
|
||||
<div className="relative w-100 ph4 pt2 pb4">
|
||||
<input className="ba b--gray3 white-d bg-gray0-d inter w-100 f9 pa2"
|
||||
|
Loading…
Reference in New Issue
Block a user