leap: add "other" actions, prepopulate results

This commit is contained in:
Matilde Park 2020-09-01 16:01:29 -04:00
parent 97e84f96f2
commit 37786327f4
3 changed files with 86 additions and 33 deletions

View File

@ -4,7 +4,8 @@ import defaultApps from './default-apps';
['commands', []],
['subscriptions', []],
['groups', []],
['apps', []]
['apps', []],
['other', []]
]);
// result schematic
@ -41,8 +42,6 @@ const commandIndex = function () {
}
});
commands.push(result('Profile', '/~profile', 'profile', null));
return commands;
};
@ -54,6 +53,9 @@ const appIndex = function (apps) {
.filter((e) => {
return apps[e]?.type?.basic;
})
.sort((a,b) => {
return a.localeCompare(b);
})
.map((e) => {
const obj = result(
apps[e].type.basic.title,
@ -70,6 +72,14 @@ const appIndex = function (apps) {
return applications;
};
const otherIndex = function() {
const other = [];
other.push(result('Profile and Settings', '/~profile/identity', 'profile', null));
other.push(result('Log Out', '/~/logout', 'logout', null));
return other;
};
export default function index(associations, apps) {
// all metadata from all apps is indexed
// into subscriptions and groups
@ -118,6 +128,7 @@ export default function index(associations, apps) {
indexes.set('subscriptions', subscriptions);
indexes.set('groups', groups);
indexes.set('apps', appIndex(apps));
indexes.set('other', otherIndex());
return indexes;
};

View File

@ -26,11 +26,15 @@ export class Omnibox extends Component {
this.renderResults = this.renderResults.bind(this);
}
componentDidUpdate(prevProps) {
componentDidUpdate(prevProps, prevState) {
if (prevProps !== this.props) {
this.setState({ index: index(this.props.associations, this.props.apps.tiles) });
}
if (prevProps && (prevProps.apps !== this.props.apps) && (this.state.query === '')) {
this.setState({ results: this.initialResults() });
}
if (prevProps && this.props.show && prevProps.show !== this.props.show) {
Mousetrap.bind('escape', () => this.props.api.local.setOmnibox());
document.addEventListener('mousedown', this.handleClickOutside);
@ -48,7 +52,7 @@ export class Omnibox extends Component {
}
getSearchedCategories() {
return ['apps', 'commands', 'groups', 'subscriptions'];
return ['apps', 'commands', 'groups', 'subscriptions', 'other'];
}
control(evt) {
@ -91,7 +95,18 @@ export class Omnibox extends Component {
}
initialResults() {
return new Map(this.getSearchedCategories().map(category => [category, []]));
return new Map(this.getSearchedCategories().map((category) => {
if (!this.state) {
return [category, []];
}
if (category === 'apps') {
return ['apps', this.state.index.get('apps')];
}
if (category === 'other') {
return ['other', this.state.index.get('other')];
}
return [category, []];
}));
}
navigate(link) {
@ -202,10 +217,12 @@ export class Omnibox extends Component {
{this.getSearchedCategories()
.map(category => Object({ category, categoryResults: state.results.get(category) }))
.filter(category => category.categoryResults.length > 0)
.map(({ category, categoryResults }, i) => (
<Box key={i} width='max(50vw, 300px)' maxWidth='600px'>
.map(({ category, categoryResults }, i) => {
const categoryTitle = (category === 'other')
? null : <Text gray ml={2}>{category.charAt(0).toUpperCase() + category.slice(1)}</Text>;
return (<Box key={i} width='max(50vw, 300px)' maxWidth='600px'>
<Rule borderTopWidth="0.5px" color="washedGray" />
<Text gray ml={2}>{category.charAt(0).toUpperCase() + category.slice(1)}</Text>
{categoryTitle}
{categoryResults.map((result, i2) => (
<OmniboxResult
key={i2}
@ -218,7 +235,8 @@ export class Omnibox extends Component {
dark={props.dark} />
))}
</Box>
))
);
})
}
</Box>;
}

View File

@ -1,6 +1,7 @@
import React, { Component } from 'react';
import { Row, Icon, Text } from '@tlon/indigo-react';
import defaultApps from '~/logic/lib/default-apps';
import Sigil from '~/logic/lib/sigil';
export class OmniboxResult extends Component {
constructor(props) {
@ -24,35 +25,58 @@ export class OmniboxResult extends Component {
}
}
setHover(boolean) {
this.setState({ hovered: boolean });
}
render() {
const { icon, text, subtext, link, navigate, selected, dark } = this.props;
let invertGraphic = {};
getIcon(icon, dark, selected, link) {
// graphicStyle is only necessary for pngs
//
//TODO can be removed after indigo-react 1.2
//which includes icons for apps
let graphicStyle = {};
if (icon.toLowerCase() !== 'dojo') {
invertGraphic = (!dark && this.state.hovered) ||
selected === link ||
(dark && !(this.state.hovered || selected === link))
? { filter: 'invert(1)', paddingTop: 2 }
: { filter: 'invert(0)', paddingTop: 2 };
} else {
invertGraphic =
(!dark && this.state.hovered) ||
graphicStyle = (!dark && this.state.hovered) ||
selected === link ||
(dark && !(this.state.hovered || selected === link))
? { filter: 'invert(0)', paddingTop: 2 }
: { filter: 'invert(1)', paddingTop: 2 };
? { filter: 'invert(1)' }
: { filter: 'invert(0)' };
} else {
graphicStyle =
(!dark && this.state.hovered) ||
selected === link ||
(dark && !(this.state.hovered || selected === link))
? { filter: 'invert(0)' }
: { filter: 'invert(1)' };
}
const iconFill = this.state.hovered || selected === link ? 'white' : 'black';
const sigilFill = this.state.hovered || selected === link ? '#3a8ff7' : '#ffffff';
let graphic = <div />;
if (defaultApps.includes(icon.toLowerCase()) || icon.toLowerCase() === 'links') {
graphic = <img className="mr2 v-mid" height="12" width="12" src={`/~landscape/img/${icon.toLowerCase()}.png`} style={invertGraphic} />;
graphic =
<img className="mr2 v-mid dib" height="16"
width="16" src={`/~landscape/img/${icon.toLowerCase()}.png`}
style={graphicStyle}
/>;
} else if (icon === 'logout') {
graphic = <Icon display="inline-block" verticalAlign="middle" icon='ArrowWest' mr='2' size='16px' fill={iconFill} />;
} else if (icon === 'profile') {
graphic = <Sigil color={sigilFill} classes='dib v-mid mr2' ship={window.ship} size={16} />;
} else {
graphic = <Icon verticalAlign="middle" mr={2} size="12px" />;
graphic = <Icon verticalAlign="middle" mr='2' size="16px" fill={iconFill} />;
}
return graphic;
}
setHover(boolean) {
this.setState({ hovered: boolean });
}
render() {
const { icon, text, subtext, link, navigate, selected, dark } = this.props;
const graphic = this.getIcon(icon, dark, selected, link);
return (
<Row
py='2'
@ -72,18 +96,18 @@ export class OmniboxResult extends Component {
{this.state.hovered || selected === link ? (
<>
{graphic}
<Text color='white' mr='1' style={{ 'flex-shrink': 0 }}>
<Text display="inline-block" verticalAlign="middle" color='white' mr='1' style={{ 'flex-shrink': 0 }}>
{text}
</Text>
<Text pr='2' color='white' width='100%' textAlign='right'>
<Text pr='2' display="inline-block" verticalAlign="middle" color='white' width='100%' textAlign='right'>
{subtext}
</Text>
</>
) : (
<>
{graphic}
<Text mr='1' style={{ 'flex-shrink': 0 }}>{text}</Text>
<Text pr='2' gray width='100%' textAlign='right'>
<Text mr='1' display="inline-block" verticalAlign="middle" style={{ 'flex-shrink': 0 }}>{text}</Text>
<Text pr='2' display="inline-block" verticalAlign="middle" gray width='100%' textAlign='right'>
{subtext}
</Text>
</>