mirror of
https://github.com/urbit/shrub.git
synced 2024-12-01 06:35:32 +03:00
Merge branch 'release/next-userspace' into lf/settings-screen
This commit is contained in:
commit
a8e4e00627
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ef417c3092dc32d6d5897a7ba63f3f8910f928f0aa23adf3a356b88ce027a415
|
||||
size 6260173
|
||||
oid sha256:6cd7246753c12c7acb757e1a6ee54c177806c20a137ad8fb4300c000ac146a0f
|
||||
size 6260139
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -23,6 +23,6 @@
|
||||
<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>
|
||||
</body>
|
||||
</html>
|
||||
|
16
pkg/interface/package-lock.json
generated
16
pkg/interface/package-lock.json
generated
@ -7589,9 +7589,9 @@
|
||||
}
|
||||
},
|
||||
"property-expr": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.2.tgz",
|
||||
"integrity": "sha512-bc/5ggaYZxNkFKj374aLbEDqVADdYaLcFo8XBkishUWbaAdjlphaBFns9TvRA2pUseVL/wMFmui9X3IdNDU37g=="
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.3.tgz",
|
||||
"integrity": "sha512-TEMKBo6s4gZUKmNYwaMkS2JdDxdWgUijW/U/jLAOHVyLZfU1KHXv+mC1J9gkfGOr8532XHqMJytko1lSjc0kmw=="
|
||||
},
|
||||
"proxy-addr": {
|
||||
"version": "2.0.6",
|
||||
@ -12119,16 +12119,16 @@
|
||||
}
|
||||
},
|
||||
"yup": {
|
||||
"version": "0.29.1",
|
||||
"resolved": "https://registry.npmjs.org/yup/-/yup-0.29.1.tgz",
|
||||
"integrity": "sha512-U7mPIbgfQWI6M3hZCJdGFrr+U0laG28FxMAKIgNvgl7OtyYuUoc4uy9qCWYHZjh49b8T7Ug8NNDdiMIEytcXrQ==",
|
||||
"version": "0.29.3",
|
||||
"resolved": "https://registry.npmjs.org/yup/-/yup-0.29.3.tgz",
|
||||
"integrity": "sha512-RNUGiZ/sQ37CkhzKFoedkeMfJM0vNQyaz+wRZJzxdKE7VfDeVKH8bb4rr7XhRLbHJz5hSjoDNwMEIaKhuMZ8gQ==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.9.6",
|
||||
"@babel/runtime": "^7.10.5",
|
||||
"fn-name": "~3.0.0",
|
||||
"lodash": "^4.17.15",
|
||||
"lodash-es": "^4.17.11",
|
||||
"property-expr": "^2.0.2",
|
||||
"synchronous-promise": "^2.0.10",
|
||||
"synchronous-promise": "^2.0.13",
|
||||
"toposort": "^2.0.2"
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@
|
||||
"suncalc": "^1.8.0",
|
||||
"urbit-ob": "^5.0.0",
|
||||
"urbit-sigil-js": "^1.3.2",
|
||||
"yup": "^0.29.1"
|
||||
"yup": "^0.29.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.9.0",
|
||||
|
@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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?
|
||||
|
@ -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)
|
||||
|
@ -15,7 +15,8 @@ const ReconnectButton = ({ connection, subscription }) => {
|
||||
color='red'
|
||||
bg="white"
|
||||
border={1}
|
||||
lineHeight='min'
|
||||
verticalAlign="middle"
|
||||
lineHeight='0'
|
||||
borderRadius={2}
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={reconnect}>
|
||||
@ -30,8 +31,9 @@ const ReconnectButton = ({ connection, subscription }) => {
|
||||
ml={2}
|
||||
px={2}
|
||||
py={1}
|
||||
lineHeight="min"
|
||||
bg='white'
|
||||
lineHeight="0"
|
||||
verticalAlign="middle"
|
||||
display='inline-block'
|
||||
color='yellow'
|
||||
border={1}
|
||||
|
@ -2,12 +2,13 @@ import React from 'react';
|
||||
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { Box, Text, Row } from '@tlon/indigo-react';
|
||||
|
||||
import ReconnectButton from './ReconnectButton';
|
||||
import { StatusBarItem } from './StatusBarItem';
|
||||
|
||||
import { Sigil } from '~/logic/lib/sigil';
|
||||
|
||||
const StatusBar = (props) => {
|
||||
function StatusBar(props) {
|
||||
const location = useLocation();
|
||||
const atHome = Boolean(location.pathname === '/');
|
||||
|
||||
@ -36,8 +37,8 @@ const StatusBar = (props) => {
|
||||
<img
|
||||
className='invert-d'
|
||||
src='/~landscape/img/icon-home.png'
|
||||
height='12'
|
||||
width='12'
|
||||
height='11'
|
||||
width='11'
|
||||
/>
|
||||
</StatusBarItem>
|
||||
)}
|
||||
@ -62,8 +63,8 @@ const StatusBar = (props) => {
|
||||
<img
|
||||
className='invert-d v-mid'
|
||||
src='/~landscape/img/groups.png'
|
||||
height='16'
|
||||
width='16'
|
||||
height='15'
|
||||
width='15'
|
||||
/>
|
||||
<Text display={["none", "inline"]} ml={2}>Groups</Text>
|
||||
</StatusBarItem>
|
||||
@ -71,7 +72,6 @@ const StatusBar = (props) => {
|
||||
<Sigil ship={props.ship} size={24} color={"#000000"} classes="dib mix-blend-diff" />
|
||||
<Text ml={2} display={["none", "inline"]} fontFamily="mono">{props.ship}</Text>
|
||||
</StatusBarItem>
|
||||
|
||||
</Row>
|
||||
</Box>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user