soto: add os1 chrome and styles, popout

This commit is contained in:
Matilde Park 2020-01-28 16:59:51 -05:00
parent e7035ebc4c
commit 82462c9007
16 changed files with 338 additions and 49 deletions

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 679 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 773 B

View File

@ -6,9 +6,12 @@
<meta name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
<link rel="stylesheet" href="/~dojo/css/index.css" />
<link rel="icon" type="image/png" href="/~launch/img/Favicon.png">
</head>
<body class="bg-black">
<div id="root" />
<body class="w-100 h-100">
<div id="header" class="w-100"></div>
<div id="root" class="w-100 h-100">
</div>
<script src="/~/channel/channel.js"></script>
<script src="/~modulo/session.js"></script>
<script src="/~dojo/js/index.js"></script>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1083,6 +1083,25 @@
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
"dev": true
},
"deep-rename-keys": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/deep-rename-keys/-/deep-rename-keys-0.2.1.tgz",
"integrity": "sha1-7eeFN9emaivmFRfir5Vtf1ij8dg=",
"requires": {
"kind-of": "^3.0.2",
"rename-keys": "^1.1.2"
},
"dependencies": {
"kind-of": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
"requires": {
"is-buffer": "^1.1.5"
}
}
}
},
"default-compare": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz",
@ -1408,6 +1427,11 @@
"integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==",
"dev": true
},
"eventemitter3": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz",
"integrity": "sha1-teEHm1n7XhuidxwKmTvgYKWMmbo="
},
"expand-brackets": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
@ -2278,8 +2302,7 @@
"get-value": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
"integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
"dev": true
"integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg="
},
"glob-parent": {
"version": "3.1.0",
@ -2951,6 +2974,14 @@
"integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==",
"dev": true
},
"invariant": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
"requires": {
"loose-envify": "^1.0.0"
}
},
"invert-kv": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
@ -3011,8 +3042,7 @@
"is-buffer": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
"dev": true
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
},
"is-callable": {
"version": "1.1.4",
@ -3156,7 +3186,6 @@
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
"integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
"dev": true,
"requires": {
"isobject": "^3.0.1"
}
@ -3244,8 +3273,7 @@
"isobject": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
"dev": true
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
},
"js-tokens": {
"version": "4.0.0",
@ -3964,6 +3992,56 @@
"has": "^1.0.3"
}
},
"omit-deep": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/omit-deep/-/omit-deep-0.3.0.tgz",
"integrity": "sha1-IcivNJm8rdKWUaIyy8rLxSRF6+w=",
"requires": {
"is-plain-object": "^2.0.1",
"unset-value": "^0.1.1"
},
"dependencies": {
"has-value": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
"integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
"requires": {
"get-value": "^2.0.3",
"has-values": "^0.1.4",
"isobject": "^2.0.0"
},
"dependencies": {
"isobject": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
"integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
"requires": {
"isarray": "1.0.0"
}
}
}
},
"has-values": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
"integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E="
},
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
},
"unset-value": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/unset-value/-/unset-value-0.1.2.tgz",
"integrity": "sha1-UGgQuGfyfCpabpsEgzYx9t5Y0xA=",
"requires": {
"has-value": "^0.3.1",
"isobject": "^3.0.0"
}
}
}
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@ -4780,6 +4858,11 @@
"integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
"dev": true
},
"rename-keys": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/rename-keys/-/rename-keys-1.2.0.tgz",
"integrity": "sha512-U7XpAktpbSgHTRSNRrjKSrjYkZKuhUukfoBlXWXUExCAqhzh1TU3BDRAfJmarcl5voKS+pbKU9MvyLWKZ4UEEg=="
},
"repeat-element": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
@ -5444,6 +5527,16 @@
"util.promisify": "~1.0.0"
}
},
"svgson": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/svgson/-/svgson-4.0.0.tgz",
"integrity": "sha512-4xmo8f7IREKzSimfKLxdFmffWn8ngstS6EYC8Hqoo4twyzLxc1BETdSBz++wx8k9s8EH8hLNi+VoH+7T2pkIgw==",
"requires": {
"deep-rename-keys": "^0.2.1",
"omit-deep": "0.3.0",
"xml-reader": "2.4.3"
}
},
"terser": {
"version": "3.17.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-3.17.0.tgz",
@ -5597,6 +5690,11 @@
"through2": "^2.0.3"
}
},
"transformation-matrix": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/transformation-matrix/-/transformation-matrix-2.1.1.tgz",
"integrity": "sha512-74MoNHhwLVuzwaPDcAecFjSkOA9vwWqyOdkeB0Be8Jc/IWSS5SNZKapFllqzkTliqZptkvqX5CZnVeDvfhN8cw=="
},
"type": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/type/-/type-1.0.1.tgz",
@ -5748,6 +5846,17 @@
"lodash.isequal": "^4.5.0"
}
},
"urbit-sigil-js": {
"version": "1.3.13",
"resolved": "https://registry.npmjs.org/urbit-sigil-js/-/urbit-sigil-js-1.3.13.tgz",
"integrity": "sha512-g6tC7K65O/4rMCd9/Cy+BVyVSzC3GNjfd0R4EaXEl4aXnjRIiIkD0xkZl56yzLwNk6W9bniDQJALcGPxY3IROw==",
"requires": {
"invariant": "^2.2.4",
"react": "^16.8.6",
"svgson": "^4.0.0",
"transformation-matrix": "2.1.1"
}
},
"urix": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
@ -5903,6 +6012,23 @@
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"xml-lexer": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/xml-lexer/-/xml-lexer-0.2.2.tgz",
"integrity": "sha1-UYGTpKozTVj8fSSLVJB5uJkH4EY=",
"requires": {
"eventemitter3": "^2.0.0"
}
},
"xml-reader": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/xml-reader/-/xml-reader-2.4.3.tgz",
"integrity": "sha1-n4EMr3xCWlqvuEixxFEDyecddTA=",
"requires": {
"eventemitter3": "^2.0.0",
"xml-lexer": "^0.2.2"
}
},
"xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",

View File

@ -34,7 +34,8 @@
"react": "^16.5.2",
"react-dom": "^16.8.6",
"react-router-dom": "^5.0.0",
"urbit-ob": "^4.1.2"
"urbit-ob": "^4.1.2",
"urbit-sigil-js": "^1.3.2"
},
"resolutions": {
"natives": "1.1.3"

View File

@ -1,3 +1,9 @@
html, body {
-webkit-font-smoothing: antialiased;
height: 100%;
width: 100%;
overflow: hidden;
}
p, input {
margin-block-end: unset;
margin-block-start: unset;
@ -29,6 +35,10 @@ textarea, select, input, button {
line-height: 24px;
}
a {
text-decoration: none;
}
.label-small-mono {
font-size: 12px;
line-height: 24px;
@ -39,7 +49,28 @@ textarea, select, input, button {
font-family: "Source Code Pro", monospace;
}
.inter {
font-family: "Inter", sans-serif;
}
input {
background-color: inherit;
color: inherit;
}
.invert {
filter: invert(1);
}
/* responsive */
@media all and (max-width: 34.375em) {
.h-100-m40-s {
height: calc(100% - 40px);
}
}
@media all and (min-width: 34.375em) {
.h-100-m40-p1-ns {
height: calc(100% - (40px + 1rem));
}
}

View File

@ -1,5 +1,6 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { HeaderBar } from '/components/lib/header-bar';
import { Root } from '/components/root';
import { api } from '/api';
import { subscription } from "/subscription";
@ -11,6 +12,8 @@ api.setAuthTokens({
subscription.start();
ReactDOM.render(<HeaderBar />, document.getElementById("header"));
ReactDOM.render((
<Root />
), document.querySelectorAll("#root")[0]);

View File

@ -6,16 +6,22 @@ export class History extends Component {
}
render() {
return (
<div className="flex flex-column-reverse overflow-container"
style={{ height: 'calc(100% - 1rem)', resize: 'vertical' }}>
<div style={{ marginTop: 'auto'}}>
<div
className="relative flex flex-column-reverse overflow-container"
style={{ height: "calc(100% - 1rem)", resize: "none" }}>
<div style={{ marginTop: "auto" }}>
{this.props.commandLog.map((text, index) => {
return <p className="mono" key={index}>{text}</p>
return (
<p className="mono" key={index}>
{text}
</p>
);
})}
</div>
</div>
)
);
}
}

View File

@ -2,29 +2,53 @@ import React, { Component } from 'react';
import classnames from 'classnames';
import { IconHome } from '/components/lib/icons/icon-home';
import { IconSpinner } from '/components/lib/icons/icon-spinner';
import { Sigil } from '/components/lib/icons/sigil';
export class HeaderBar extends Component {
render() {
let spin = (this.props.spinner)
? <div className="absolute"
style={{width: 16, height: 16, top: 16, right: 16}}>
<IconSpinner/>
</div>
: null;
// let spin = (this.props.spinner)
// ? <div className="absolute"
// style={{width: 16, height: 16, top: 16, left: 55}}>
// <IconSpinner/>
// </div>
// : null;
let popout = (window.location.href.includes("popout"))
? "dn"
: "dn db-m db-l db-xl";
let title = (document.title === "Home")
? ""
: document.title;
return (
<div className="bg-black w-100 justify-between b--gray0 bb"
style={{ height: 48, padding: 8}}>
<a className="db"
style={{ background: '#1A1A1A',
borderRadius: 16,
width: 32,
height: 32,
top: 8 }}
href='/'>
<div className={"bg-gray1 w-100 justify-between relative tc pt3 "
+ popout}
style={{ height: 40 }}>
<a className="dib white f9 inter absolute left-1"
href='/'
style={{ top: 14 }}>
<IconHome />
<span className="ml2 white v-top lh-title"
style={{ paddingTop: 3 }}>
Home
</span>
</a>
{spin}
<span className="f9 white inter dib"
style={{
verticalAlign: "text-top",
paddingTop: 3
}}>{title}</span>
{/* {spin} */}
<div className="absolute right-1 lh-copy"
style={{ top: 12 }}>
<Sigil
ship={"~" + window.ship}
size={16}
color={"#4d4d4d"}
/>
<span className="mono white f9 ml2 v-top">{"~" + window.ship}</span>
</div>
</div>
);
}

View File

@ -1,9 +1,15 @@
import React, { Component } from 'react';
import React, { Component } from "react";
export class IconHome extends Component {
render() {
return (
<img src="/~launch/img/Home.png" width={32} height={32} />
//TODO relocate to ~launch when OS1 is ported
<img
className="invert"
src="/~link/img/Home.png"
width={16}
height={16}
/>
);
}
}

View File

@ -0,0 +1,28 @@
import React, { Component } from 'react'
export class Popout extends Component {
render() {
let hidePopoutIcon = this.props.popout
? "dn-m dn-l dn-xl"
: "dib-m dib-l dib-xl";
return (
<div
className="dib absolute z-2"
style={{
right: 16,
top: 16
}}>
<a href="/~dojo/popout" target="_blank">
<img
className={`flex-shrink-0 dn ` + hidePopoutIcon}
src="/~dojo/img/popout.png"
height="16"
width="16"
/>
</a>
</div>
);
}
}
export default Popout

View File

@ -0,0 +1,27 @@
import React, { Component } from 'react';
import { sigil, reactRenderer } from 'urbit-sigil-js';
export class Sigil extends Component {
render() {
const { props } = this;
if (props.ship.length > 14) {
return (
<div className="bg-black flex-shrink-0" style={{ width: props.size, height: props.size }}>
</div>
);
} else {
return (
<div className="dib flex-shrink-0" style={{ flexBasis: 32, backgroundColor: props.color }}>
{sigil({
patp: props.ship,
renderer: reactRenderer,
size: props.size,
colors: [props.color, "white"]
})}
</div>
);
}
}
}

View File

@ -2,7 +2,7 @@ import React, { Component } from 'react';
import { BrowserRouter, Route } from "react-router-dom";
import classnames from 'classnames';
import _ from 'lodash';
import { HeaderBar } from './lib/header-bar';
import { Popout } from './lib/icons/popout';
import { History } from './history';
import { Input } from './input';
import { api } from '../api';
@ -18,19 +18,53 @@ export class Root extends Component {
render() {
return (
<BrowserRouter>
<div style={{height: "100vh"}}>
<HeaderBar/>
<Route exact path="/~dojo" render={ () => {
return (
<div className="pa3 bg-black mono gray3 w-100"
style={{lineHeight: "1.4", height: "calc(100% - 48px)", cursor: "text"}}>
<History commandLog={this.state.txt}/>
<Input ship={ship} cursor={this.state.cursor} prompt={this.state.prompt} input={this.state.input}/>
</div>
)}}
/>
<div className="w-100 h-100 bg-gray1">
<Route
exact path="/~dojo/:popout?"
render={(props) => {
let popout = !!props.match.params.popout;
let popoutClasses = classnames({
"h-100-m40-p1-ns": !popout,
"h-100-m h-100-l h-100-xl": popout,
"mh4-m mh4-l mh4-xl": !popout,
"mb4-m mb4-l mb4-xl": !popout,
"ba-m ba-l ba-xl": !popout
})
return (
<div className="w-100 h-100 flex-m flex-l flex-xl">
<div
className="db dn-m dn-l dn-xl inter bg-gray0 dt w-100"
style={{ height: 40 }}>
<a className="f8 pl3 white dtc h-100 v-mid" href="/">
Landscape
</a>
</div>
<div
className={
`pa3 bg-gray0 mono white w-100
h-100-m40-s b--gray0 br2 f8 relative ` + popoutClasses
}
style={{
lineHeight: "1.4",
cursor: "text"
}}>
<Popout popout={popout}/>
<History commandLog={this.state.txt} />
<Input
ship={ship}
cursor={this.state.cursor}
prompt={this.state.prompt}
input={this.state.input}
/>
</div>
</div>
);
}}
/>
</div>
</BrowserRouter>
)
);
}
}