Merge branch 'release/next-userspace' of https://github.com/urbit/urbit into dojo-leap-conflict

This commit is contained in:
Tyler Brown Cifu Shuster 2020-08-17 15:49:53 -07:00
commit 9e512eb17f
11 changed files with 125 additions and 153 deletions

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ef417c3092dc32d6d5897a7ba63f3f8910f928f0aa23adf3a356b88ce027a415
size 6260173
oid sha256:6cd7246753c12c7acb757e1a6ee54c177806c20a137ad8fb4300c000ac146a0f
size 6260139

View File

@ -153,9 +153,13 @@
=* headers header-list.req
=/ req-line (parse-request-line url.req)
?. =(method.req %'GET') not-found:gen
=. site.req-line
%+ murn site.req-line
|= =cord
^- (unit ^cord)
?:(=(cord '') ~ `cord)
=? req-line ?=(~ ext.req-line)
[[[~ %html] ~['index']] args.req-line]
?> ?=(^ ext.req-line)
[[[~ %html] (snoc site.req-line 'index')] args.req-line]
?~ site.req-line
not-found:gen
=* url-prefix landscape-homepage-prefix.configuration
@ -177,7 +181,9 @@
++ get-file
|= req-line=request-line
^- [simple-payload:http ?]
=/ pax=path (snoc site.req-line (need ext.req-line))
=/ pax=path
?~ ext.req-line site.req-line
(snoc site.req-line u.ext.req-line)
=/ content=(unit [=content suffix=path public=?]) (get-content pax)
?~ content [not-found:gen %.n]
?- -.content.u.content

View File

@ -1,7 +1,7 @@
/- glob
/+ default-agent, verb, dbug
|%
++ hash 0v7.foe2o.ang8k.28dnr.fudi0.74c8d
++ hash 0v2.pbthv.gd1q2.h2ura.5esrn.d361c
+$ state-0 [%0 hash=@uv glob=(unit (each glob:glob tid=@ta))]
+$ all-states
$% state-0

View File

@ -23,7 +23,7 @@
<div id="root"></div>
<script src="/~landscape/js/channel.js"></script>
<script src="/~landscape/js/session.js"></script>
<script src="/~landscape/js/bundle/index.8e25dc41456a44c967da.js"></script>
<script src="/~landscape/js/bundle/index.f58fbbc4b037bb976a2a.js"></script>
<script src="https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js"></script>
</body>
</html>

Binary file not shown.

View File

@ -32,7 +32,8 @@
"styled-system": "^5.1.5",
"suncalc": "^1.8.0",
"urbit-ob": "^5.0.0",
"urbit-sigil-js": "^1.3.2"
"urbit-sigil-js": "^1.3.2",
"yup": "^0.29.3"
},
"devDependencies": {
"@babel/core": "^7.9.0",

View File

@ -1,146 +1,100 @@
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { Spinner } from '~/views/components/Spinner';
import { Spinner } from '../../../components/Spinner';
import urbitOb from 'urbit-ob';
import { Box, Text, Input, Button } from '@tlon/indigo-react';
import { Formik, Form } from 'formik'
import * as Yup from 'yup';
const schema = Yup.object().shape({
station: Yup.string()
.lowercase()
.trim()
.test('is-station',
'Chat must have a valid name',
(val) =>
val &&
val.split('/').length === 2 &&
urbitOb.isValidPatp(val.split('/')[0])
)
.required('Required')
});
export class JoinScreen extends Component {
constructor(props) {
super(props);
this.state = {
station: '/',
error: false,
awaiting: false
};
this.stationChange = this.stationChange.bind(this);
}
componentDidMount() {
this.componentDidUpdate();
if (this.props.station) {
this.onSubmit({ station: this.props.station });
}
}
componentDidUpdate(prevProps, prevState) {
const { props, state } = this;
if ((props.autoJoin !== '/undefined/undefined') &&
(props.api && (prevProps?.api !== props.api))) {
let station = props.autoJoin.split('/');
const ship = station[1];
if (
station.length < 2 ||
!urbitOb.isValidPatp(ship)
) {
this.setState({
error: true
});
onSubmit(values) {
console.log(values);
this.setState({ awaiting: true }, () => {
console.log(values);
const station = values.station.trim();
if (`/${station}` in this.props.chatSynced) {
this.props.history.push(`/~chat/room/${station}`);
return;
}
station = props.autoJoin;
this.setState({
station,
awaiting: true
}, () => props.api.chat.join(ship, station, true));
}
if (state.station in props.inbox ||
(props?.chatSynced !== prevProps?.chatSynced && state.station !== '/')) {
this.setState({ awaiting: false });
props.history.push(`/~chat/room${state.station}`);
}
}
onClickJoin() {
const { props, state } = this;
let station = state.station.split('/');
const ship = station[1];
if (
station.length < 2 ||
!urbitOb.isValidPatp(ship)
) {
this.setState({
error: true
});
return;
}
station = state.station.trim();
this.setState({
station,
awaiting: true
}, () => {
props.api.chat.join(ship, station, true);
});
}
stationChange(event) {
this.setState({
station: `/${event.target.value.trim()}`
props.api.chat.join(ship, station, true)
this.props.history.push(`/~chat/room/${station}`);
});
}
render() {
const { state } = this;
let joinClasses = 'db f9 green2 ba pa2 b--green2 bg-gray0-d pointer';
if ((!state.station) || (state.station === '/')) {
joinClasses = 'db f9 gray2 ba pa2 b--gray3 bg-gray0-d pointer';
}
let errElem = (<span />);
if (state.error) {
errElem = (
<span className="f9 inter red2 db">
Chat must have a valid name.
</span>
);
}
const { props, state } = this;
return (
<div className={`h-100 w-100 pa3 pt2 overflow-x-hidden flex flex-column
bg-gray0-d white-d`}
>
<div
className="w-100 dn-m dn-l dn-xl inter pt1 pb6 f8"
>
<Link to="/~chat/">{'⟵ All Chats'}</Link>
</div>
<h2 className="mb3 f8">Join Existing Chat</h2>
<div className="w-100">
<p className="f8 lh-copy mt3 db">Enter a <span className="mono">~ship/chat-name</span></p>
<p className="f9 gray2 mb4">Chat names use lowercase, hyphens, and slashes.</p>
<textarea
ref={ (e) => {
this.textarea = e;
} }
className={'f7 mono ba bg-gray0-d white-d pa3 mb2 db ' +
'focus-b--black focus-b--white-d b--gray3 b--gray2-d'}
placeholder="~zod/chatroom"
spellCheck="false"
rows={1}
onKeyPress={(e) => {
if (e.key === 'Enter') {
this.onClickJoin();
}
}}
style={{
resize: 'none'
}}
onChange={this.stationChange}
/>
{errElem}
<br />
<button
onClick={this.onClickJoin.bind(this)}
className={joinClasses}
>Join Chat</button>
<Spinner awaiting={this.state.awaiting} classes="mt4" text="Joining chat..." />
</div>
</div>
<Formik
enableReinitialize={true}
initialValues={{ station: props.station }}
validationSchema={schema}
onSubmit={this.onSubmit.bind(this)}>
<Form>
<Box width="100%" height="100%" p={3} overflowX="hidden">
<Box
width="100%"
pt={1} pb={5}
display={['', 'none', 'none', 'none']}
fontSize={0}>
<Link to="/~chat/">{'⟵ All Chats'}</Link>
</Box>
<Text mb={3} fontSize={0}>Join Existing Chat</Text>
<Box width="100%" maxWidth={350}>
<Box mt={3} mb={3} display="block">
<Text display="inline" fontSize={0}>
Enter a{' '}
</Text>
<Text display="inline" fontSize={0} fontFamily="mono">
~ship/chat-name
</Text>
</Box>
<Input
mt={4}
id="station"
placeholder="~zod/chatroom"
fontFamily="mono"
caption="Chat names use lowercase, hyphens, and slashes." />
<Button>Join Chat</Button>
<Spinner
awaiting={this.state.awaiting}
classes="mt4"
text="Joining chat..." />
</Box>
</Box>
</Form>
</Formik>
);
}
}

View File

@ -41,7 +41,7 @@ export default class TextContent extends Component {
const content = props.content;
const group = content.text.match(
/([~][/])?(~[a-z]{3,6})(-[a-z]{6})?([/])(([a-z])+([/-])?)+/
/([~][/])?(~[a-z]{3,6})(-[a-z]{6})?([/])(([a-z0-9-])+([/-])?)+/
);
if ((group !== null) // matched possible chatroom
&& (group[2].length > 2) // possible ship?

View File

@ -192,7 +192,13 @@ export class Omnibox extends Component {
renderResults() {
const { props, state } = this;
return <Box maxHeight="400px" overflowY="scroll" overflowX="hidden">
return <Box
maxHeight="400px"
overflowY="auto"
overflowX="hidden"
borderBottomLeftRadius='2'
borderBottomRightRadius='2'
>
{this.getSearchedCategories()
.map(category => Object({ category, categoryResults: state.results.get(category) }))
.filter(category => category.categoryResults.length > 0)

View File

@ -8,13 +8,14 @@ const ReconnectButton = ({ connection, subscription }) => {
return (
<>
<Box
ml={4}
ml={2}
px={2}
py={1}
display='inline-block'
color='red'
border={1}
lineHeight='min'
verticalAlign="middle"
lineHeight='0'
borderRadius={2}
style={{ cursor: 'pointer' }}
onClick={reconnect}>
@ -26,10 +27,11 @@ const ReconnectButton = ({ connection, subscription }) => {
return (
<>
<Box
ml={4}
ml={2}
px={2}
py={1}
lineHeight="min"
lineHeight="0"
verticalAlign="middle"
display='inline-block'
color='yellow'
border={1}

View File

@ -1,15 +1,12 @@
import React from 'react';
import { useLocation } from 'react-router-dom';
import { Box, Text, Icon } from '@tlon/indigo-react';
import { Row, Box, Text, Icon } from '@tlon/indigo-react';
import ReconnectButton from './ReconnectButton';
const StatusBar = (props) => {
const location = useLocation();
const atHome = Boolean(location.pathname === '/');
const display = (!window.location.href.includes('popout/'))
? 'db' : 'dn';
const invites = (props.invites && props.invites['/contacts'])
? props.invites['/contacts']
: {};
@ -28,28 +25,32 @@ const StatusBar = (props) => {
);
return (
<div
className={
'bg-white bg-gray0-d w-100 justify-between relative tc pt3 ' + display
}
style={{ height: 45 }}>
<div className='absolute left-0 pl4' style={{ top: 10 }}>
<Row
height="45px"
backgroundColor="white"
width="100%"
justifyContent="space-between"
pt="10px"
display={(window.location.href.includes('popout/') ? 'none' : 'flex')}>
<Box pl={3} display="inline-block">
{atHome ? null : (
<Box
style={{ cursor: 'pointer' }}
display='inline-block'
borderRadius={2}
verticalAlign="middle"
lineHeight="0"
color='washedGray'
border={1}
py={1}
py="6px"
px={2}
mr={2}
onClick={() => props.history.push('/')}>
<img
className='invert-d'
src='/~landscape/img/icon-home.png'
height='12'
width='12'
height='11'
width='11'
/>
</Box>
)}
@ -58,8 +59,9 @@ const StatusBar = (props) => {
borderRadius={2}
color='washedGray'
display='inline-block'
verticalAlign='middle'
lineHeight="0"
style={{ cursor: 'pointer' }}
lineHeight='min'
py={1}
px={2}
onClick={() => props.api.local.setOmnibox()}>
@ -77,14 +79,15 @@ const StatusBar = (props) => {
connection={props.connection}
subscription={props.subscription}
/>
</div>
<div className='fl absolute relative right-0 pr4' style={{ top: 10 }}>
</Box>
<Box position="relative" pr={3} display="inline-block">
<Box
style={{ cursor: 'pointer' }}
display='inline-block'
borderRadius={2}
color='washedGray'
lineHeight='min'
verticalAlign="middle"
lineHeight='0'
border={1}
px={2}
py={1}
@ -92,14 +95,14 @@ const StatusBar = (props) => {
<img
className='invert-d v-mid mr1'
src='/~landscape/img/groups.png'
height='16'
width='16'
height='15'
width='15'
/>
{Notification}
<Text ml={1}>Groups</Text>
</Box>
</div>
</div>
</Box>
</Row>
);
};