mirror of
https://github.com/urbit/shrub.git
synced 2024-11-28 22:33:06 +03:00
Merge branch 'release/next-userspace' into mp/links-indigo
This commit is contained in:
commit
2c621caac2
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ef417c3092dc32d6d5897a7ba63f3f8910f928f0aa23adf3a356b88ce027a415
|
||||
size 6260173
|
||||
oid sha256:6cd7246753c12c7acb757e1a6ee54c177806c20a137ad8fb4300c000ac146a0f
|
||||
size 6260139
|
||||
|
@ -164,10 +164,7 @@
|
||||
(fact-group-update:cc wire !<(update:group-store q.cage.sign))
|
||||
[cards this]
|
||||
::
|
||||
%invite-update
|
||||
=^ cards state
|
||||
(fact-invite-update:cc wire !<(invite-update q.cage.sign))
|
||||
[cards this]
|
||||
%invite-update [~ this]
|
||||
==
|
||||
==
|
||||
::
|
||||
@ -481,17 +478,6 @@
|
||||
[%pass / %agent [our.bol %invite-hook] %poke %invite-action !>(act)]
|
||||
--
|
||||
::
|
||||
++ fact-invite-update
|
||||
|= [wir=wire fact=invite-update]
|
||||
^- (quip card _state)
|
||||
?+ -.fact [~ state]
|
||||
%accepted
|
||||
=/ rid=resource
|
||||
(de-path:resource path.invite.fact)
|
||||
:_ state
|
||||
~[(contact-view-poke %join rid)]
|
||||
==
|
||||
::
|
||||
++ group-hook-poke
|
||||
|= =action:group-hook
|
||||
^- card
|
||||
|
@ -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
|
||||
|
@ -227,8 +227,11 @@
|
||||
|
||||
++ peek-group-join
|
||||
|= [rid=resource =ship]
|
||||
=/ =group
|
||||
(~(gut by groups) rid *group)
|
||||
=/ ugroup
|
||||
(~(get by groups) rid)
|
||||
?~ ugroup
|
||||
%.n
|
||||
=* group u.ugroup
|
||||
=* policy policy.group
|
||||
?- -.policy
|
||||
%invite
|
||||
|
@ -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>
|
||||
|
@ -61,8 +61,9 @@
|
||||
^- json
|
||||
%+ frond %chat-update
|
||||
%- pairs
|
||||
:~
|
||||
?: ?=(%initial -.upd)
|
||||
:_ ~
|
||||
?- -.upd
|
||||
%initial
|
||||
:- %initial
|
||||
%- pairs
|
||||
%+ turn ~(tap by inbox.upd)
|
||||
@ -73,27 +74,37 @@
|
||||
:~ [%envelopes [%a (turn envelopes.mailbox envelope)]]
|
||||
[%config (config config.mailbox)]
|
||||
==
|
||||
?: ?=(%message -.upd)
|
||||
:- %message
|
||||
%- pairs
|
||||
:~ [%path (path path.upd)]
|
||||
[%envelope (envelope envelope.upd)]
|
||||
==
|
||||
?: ?=(%messages -.upd)
|
||||
:- %messages
|
||||
%- pairs
|
||||
:~ [%path (path path.upd)]
|
||||
[%start (numb start.upd)]
|
||||
[%end (numb end.upd)]
|
||||
[%envelopes [%a (turn envelopes.upd envelope)]]
|
||||
==
|
||||
?: ?=(%read -.upd)
|
||||
[%read (pairs [%path (path path.upd)]~)]
|
||||
?: ?=(%create -.upd)
|
||||
[%create (pairs [%path (path path.upd)]~)]
|
||||
?: ?=(%delete -.upd)
|
||||
[%delete (pairs [%path (path path.upd)]~)]
|
||||
[*@t *json]
|
||||
::
|
||||
%message
|
||||
:- %message
|
||||
%- pairs
|
||||
:~ [%path (path path.upd)]
|
||||
[%envelope (envelope envelope.upd)]
|
||||
==
|
||||
::
|
||||
%messages
|
||||
:- %messages
|
||||
%- pairs
|
||||
:~ [%path (path path.upd)]
|
||||
[%start (numb start.upd)]
|
||||
[%end (numb end.upd)]
|
||||
[%envelopes [%a (turn envelopes.upd envelope)]]
|
||||
==
|
||||
::
|
||||
%read
|
||||
[%read (pairs [%path (path path.upd)]~)]
|
||||
::
|
||||
%create
|
||||
[%create (pairs [%path (path path.upd)]~)]
|
||||
::
|
||||
%delete
|
||||
[%delete (pairs [%path (path path.upd)]~)]
|
||||
::
|
||||
%keys
|
||||
:- %keys
|
||||
:- %a
|
||||
%+ turn ~(tap by keys.upd)
|
||||
|= pax=^path (path pax)
|
||||
==
|
||||
--
|
||||
++ dejs
|
||||
|
@ -225,7 +225,8 @@
|
||||
++ add
|
||||
|= [=ship =resource]
|
||||
~| resource
|
||||
?< (~(has by tracking) resource)
|
||||
?: (~(has by tracking) resource)
|
||||
[~ state]
|
||||
=. tracking
|
||||
(~(put by tracking) resource ship)
|
||||
:_ state
|
||||
|
14
pkg/interface/.babelrc
Normal file
14
pkg/interface/.babelrc
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"plugins": [
|
||||
[
|
||||
"babel-plugin-root-import",
|
||||
{
|
||||
"paths": [
|
||||
{
|
||||
"rootPathSuffix": "./src"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
49
pkg/interface/package-lock.json
generated
49
pkg/interface/package-lock.json
generated
@ -2362,6 +2362,15 @@
|
||||
"object.assign": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"babel-plugin-root-import": {
|
||||
"version": "6.5.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-root-import/-/babel-plugin-root-import-6.5.0.tgz",
|
||||
"integrity": "sha512-PTD8fPl4v1kwn01u9d4rgRavDs5Z+jv4qa4/y6iYtoSgM4/xmjwMqo66j5A/BTZQEMA6OV5iFgyZ1PIhroJqqg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"slash": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"babel-plugin-styled-components": {
|
||||
"version": "1.10.7",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.10.7.tgz",
|
||||
@ -4793,6 +4802,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"fn-name": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fn-name/-/fn-name-3.0.0.tgz",
|
||||
"integrity": "sha512-eNMNr5exLoavuAMhIUVsOKF79SWd/zG104ef6sxBTSw+cZc6BXdQXDvYcGvp0VbxVVSp1XDUNoz7mg1xMtSznA=="
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.11.0",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.11.0.tgz",
|
||||
@ -7441,6 +7455,11 @@
|
||||
"react-is": "^16.8.1"
|
||||
}
|
||||
},
|
||||
"property-expr": {
|
||||
"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",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
|
||||
@ -8420,6 +8439,12 @@
|
||||
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
|
||||
"dev": true
|
||||
},
|
||||
"slash": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
||||
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
|
||||
"dev": true
|
||||
},
|
||||
"slice-ansi": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
|
||||
@ -9055,6 +9080,11 @@
|
||||
"xml-reader": "2.4.3"
|
||||
}
|
||||
},
|
||||
"synchronous-promise": {
|
||||
"version": "2.0.13",
|
||||
"resolved": "https://registry.npmjs.org/synchronous-promise/-/synchronous-promise-2.0.13.tgz",
|
||||
"integrity": "sha512-R9N6uDkVsghHePKh1TEqbnLddO2IY25OcsksyFp/qBe7XYd0PVbKEWxhcdMhpLzE1I6skj5l4aEZ3CRxcbArlA=="
|
||||
},
|
||||
"tabbable": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/tabbable/-/tabbable-4.0.0.tgz",
|
||||
@ -9287,6 +9317,11 @@
|
||||
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
|
||||
"dev": true
|
||||
},
|
||||
"toposort": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz",
|
||||
"integrity": "sha1-riF2gXXRVZ1IvvNUILL0li8JwzA="
|
||||
},
|
||||
"transformation-matrix": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/transformation-matrix/-/transformation-matrix-2.1.1.tgz",
|
||||
@ -11870,6 +11905,20 @@
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"yup": {
|
||||
"version": "0.29.3",
|
||||
"resolved": "https://registry.npmjs.org/yup/-/yup-0.29.3.tgz",
|
||||
"integrity": "sha512-RNUGiZ/sQ37CkhzKFoedkeMfJM0vNQyaz+wRZJzxdKE7VfDeVKH8bb4rr7XhRLbHJz5hSjoDNwMEIaKhuMZ8gQ==",
|
||||
"requires": {
|
||||
"@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.13",
|
||||
"toposort": "^2.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
"@tlon/indigo-light": "^1.0.3",
|
||||
"@tlon/indigo-react": "^1.1.15",
|
||||
"classnames": "^2.2.6",
|
||||
"codemirror": "^5.51.0",
|
||||
"codemirror": "^5.55.0",
|
||||
"css-loader": "^3.5.3",
|
||||
"formik": "^2.1.4",
|
||||
"lodash": "^4.17.15",
|
||||
@ -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",
|
||||
@ -50,6 +51,7 @@
|
||||
"@typescript-eslint/parser": "^3.8.0",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"babel-loader": "^8.1.0",
|
||||
"babel-plugin-root-import": "^6.5.0",
|
||||
"clean-webpack-plugin": "^3.0.0",
|
||||
"cross-env": "^7.0.2",
|
||||
"eslint": "^6.8.0",
|
||||
|
@ -1,6 +1,6 @@
|
||||
import _ from "lodash";
|
||||
import { uuid } from "../lib/util";
|
||||
import { Patp, Path } from "../types/noun";
|
||||
import { Patp, Path } from "~/types/noun";
|
||||
import BaseStore from '../store/base';
|
||||
|
||||
export default class BaseApi<S extends object = {}> {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import BaseApi from './base';
|
||||
import { uuid } from '../lib/util';
|
||||
import { Letter, ChatAction, Envelope } from '../types/chat-update';
|
||||
import { Patp, Path, PatpNoSig } from '../types/noun';
|
||||
import { Letter, ChatAction, Envelope } from '~/types/chat-update';
|
||||
import { Patp, Path, PatpNoSig } from '~/types/noun';
|
||||
import { StoreState } from '../store/type';
|
||||
import BaseStore from '../store/base';
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
import BaseApi from './base';
|
||||
import { StoreState } from '../store/type';
|
||||
import { Patp, Path, Enc } from '../types/noun';
|
||||
import { Contact, ContactEdit } from '../types/contact-update';
|
||||
import { GroupPolicy, Resource } from '../types/group-update';
|
||||
import { Patp, Path, Enc } from '~/types/noun';
|
||||
import { Contact, ContactEdit } from '~/types/contact-update';
|
||||
import { GroupPolicy, Resource } from '~/types/group-update';
|
||||
|
||||
export default class ContactsApi extends BaseApi<StoreState> {
|
||||
create(
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Patp } from '../types/noun';
|
||||
import { Patp } from '~/types/noun';
|
||||
import BaseApi from './base';
|
||||
import ChatApi from './chat';
|
||||
import { StoreState } from '../store/type';
|
||||
|
@ -1,13 +1,13 @@
|
||||
import BaseApi from './base';
|
||||
import { StoreState } from '../store/type';
|
||||
import { Path, Patp, Enc } from '../types/noun';
|
||||
import { Path, Patp, Enc } from '~/types/noun';
|
||||
import {
|
||||
GroupAction,
|
||||
GroupPolicy,
|
||||
Resource,
|
||||
Tag,
|
||||
GroupPolicyDiff,
|
||||
} from '../types/group-update';
|
||||
} from '~/types/group-update';
|
||||
|
||||
export default class GroupsApi extends BaseApi<StoreState> {
|
||||
remove(resource: Resource, ships: Patp[]) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import BaseApi from "./base";
|
||||
import { StoreState } from "../store/type";
|
||||
import { Serial, Path } from "../types/noun";
|
||||
import { Serial, Path } from "~/types/noun";
|
||||
|
||||
export default class InviteApi extends BaseApi<StoreState> {
|
||||
accept(app: Path, uid: Serial) {
|
||||
|
@ -2,7 +2,7 @@ import { stringToTa } from '../lib/util';
|
||||
|
||||
import BaseApi from './base';
|
||||
import { StoreState } from '../store/type';
|
||||
import { Path } from '../types/noun';
|
||||
import { Path } from '~/types/noun';
|
||||
|
||||
export default class LinksApi extends BaseApi<StoreState> {
|
||||
|
||||
|
@ -28,7 +28,7 @@ export default class LocalApi extends BaseApi<StoreState> {
|
||||
});
|
||||
}
|
||||
|
||||
setOmnibox() {
|
||||
setOmnibox() {
|
||||
this.store.handleEvent({
|
||||
data: {
|
||||
local: {
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
import BaseApi from './base';
|
||||
import { StoreState } from '../store/type';
|
||||
import { Path, Patp } from '../types/noun';
|
||||
import { Path, Patp } from '~/types/noun';
|
||||
|
||||
export default class MetadataApi extends BaseApi<StoreState> {
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import BaseApi from './base';
|
||||
import { PublishResponse } from '../types/publish-response';
|
||||
import { PatpNoSig } from '../types/noun';
|
||||
import { BookId, NoteId } from '../types/publish-update';
|
||||
import { PublishResponse } from '~/types/publish-response';
|
||||
import { PatpNoSig } from '~/types/noun';
|
||||
import { BookId, NoteId } from '~/types/publish-update';
|
||||
|
||||
export default class PublishApi extends BaseApi {
|
||||
handleEvent(data: PublishResponse) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { roleTags, RoleTags, Group, Resource } from '../../types/group-update';
|
||||
import { PatpNoSig, Path } from '../../types/noun';
|
||||
import { roleTags, RoleTags, Group, Resource } from '~/types/group-update';
|
||||
import { PatpNoSig, Path } from '~/types/noun';
|
||||
|
||||
|
||||
export function roleForShip(group: Group, ship: PatpNoSig): RoleTags | undefined {
|
||||
|
@ -1,8 +1,8 @@
|
||||
import _ from 'lodash';
|
||||
import { StoreState } from '../../../store/type';
|
||||
import { Cage } from '../../types/cage';
|
||||
import { ChatUpdate } from '../../types/chat-update';
|
||||
import { ChatHookUpdate } from '../../types/chat-hook-update';
|
||||
import { Cage } from '~/types/cage';
|
||||
import { ChatUpdate } from '~/types/chat-update';
|
||||
import { ChatHookUpdate } from '~/types/chat-hook-update';
|
||||
|
||||
type ChatState = Pick<StoreState, 'chatInitialized' | 'chatSynced' | 'inbox' | 'pendingMessages'>;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import _ from 'lodash';
|
||||
import { StoreState } from '../../store/type';
|
||||
import { Cage } from '../../types/cage';
|
||||
import { Cage } from '~/types/cage';
|
||||
|
||||
type LocalState = Pick<StoreState, 'connection'>;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import _ from 'lodash';
|
||||
import { StoreState } from '../../store/type';
|
||||
import { Cage } from '../../types/cage';
|
||||
import { ContactUpdate } from '../../types/contact-update';
|
||||
import { Cage } from '~/types/cage';
|
||||
import { ContactUpdate } from '~/types/contact-update';
|
||||
|
||||
type ContactState = Pick<StoreState, 'contacts'>;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import _ from 'lodash';
|
||||
import { StoreState } from '../../store/type';
|
||||
import { Cage } from '../../types/cage';
|
||||
import { Cage } from '~/types/cage';
|
||||
import {
|
||||
GroupUpdate,
|
||||
Group,
|
||||
@ -11,8 +11,8 @@ import {
|
||||
OpenPolicy,
|
||||
InvitePolicyDiff,
|
||||
InvitePolicy,
|
||||
} from '../../types/group-update';
|
||||
import { Enc, PatpNoSig } from '../../types/noun';
|
||||
} from '~/types/group-update';
|
||||
import { Enc, PatpNoSig } from '~/types/noun';
|
||||
import { resourceAsPath } from '../lib/util';
|
||||
|
||||
type GroupState = Pick<StoreState, 'groups' | 'groupKeys'>;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import _ from 'lodash';
|
||||
import { StoreState } from '../../store/type';
|
||||
import { Cage } from '../../types/cage';
|
||||
import { InviteUpdate } from '../../types/invite-update';
|
||||
import { Cage } from '~/types/cage';
|
||||
import { InviteUpdate } from '~/types/invite-update';
|
||||
|
||||
type InviteState = Pick<StoreState, "invites">;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import _ from 'lodash';
|
||||
import { LaunchUpdate } from '../../types/launch-update';
|
||||
import { Cage } from '../../types/cage';
|
||||
import { LaunchUpdate } from '~/types/launch-update';
|
||||
import { Cage } from '~/types/cage';
|
||||
import { StoreState } from '../../store/type';
|
||||
|
||||
type LaunchState = Pick<StoreState, 'launch' | 'weather' | 'userLocation'>;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import _ from 'lodash';
|
||||
import { StoreState } from '../../store/type';
|
||||
import { LinkUpdate, Pagination } from '../../types/link-update';
|
||||
import { LinkUpdate, Pagination } from '~/types/link-update';
|
||||
|
||||
// page size as expected from link-view.
|
||||
// must change in parallel with the +page-size in /app/link-view to
|
||||
|
@ -1,7 +1,7 @@
|
||||
import _ from 'lodash';
|
||||
import { StoreState } from '../../store/type';
|
||||
import { Cage } from '../../types/cage';
|
||||
import { LinkListenUpdate } from '../../types/link-listen-update';
|
||||
import { Cage } from '~/types/cage';
|
||||
import { LinkListenUpdate } from '~/types/link-listen-update';
|
||||
|
||||
type LinkListenState = Pick<StoreState, 'linkListening'>;
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
import _ from 'lodash';
|
||||
import { StoreState } from '../../store/type';
|
||||
import { Cage } from '../../types/cage';
|
||||
import { LocalUpdate } from '../../types/local-update';
|
||||
import { Cage } from '~/types/cage';
|
||||
import { LocalUpdate } from '~/types/local-update';
|
||||
|
||||
type LocalState = Pick<StoreState, 'sidebarShown' | 'omniboxShown' | 'dark' | 'baseHash'>;
|
||||
type LocalState = Pick<StoreState, 'sidebarShown' | 'omniboxShown' | 'dark' | 'baseHash' | 'suspendedFocus'>;
|
||||
|
||||
export default class LocalReducer<S extends LocalState> {
|
||||
reduce(json: Cage, state: S) {
|
||||
@ -24,6 +24,13 @@ export default class LocalReducer<S extends LocalState> {
|
||||
omniboxShown(obj: LocalUpdate, state: S) {
|
||||
if ('omniboxShown' in obj) {
|
||||
state.omniboxShown = !state.omniboxShown;
|
||||
if (state.suspendedFocus) {
|
||||
state.suspendedFocus.focus();
|
||||
state.suspendedFocus = null;
|
||||
} else {
|
||||
state.suspendedFocus = document.activeElement;
|
||||
document.activeElement?.blur();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,8 +2,8 @@ import _ from 'lodash';
|
||||
|
||||
import { StoreState } from '../../store/type';
|
||||
|
||||
import { MetadataUpdate } from '../../types/metadata-update';
|
||||
import { Cage } from '../../types/cage';
|
||||
import { MetadataUpdate } from '~/types/metadata-update';
|
||||
import { Cage } from '~/types/cage';
|
||||
|
||||
type MetadataState = Pick<StoreState, 'associations'>;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import _ from 'lodash';
|
||||
import { StoreState } from '../../store/type';
|
||||
import { Cage } from '../../types/cage';
|
||||
import { PermissionUpdate } from '../../types/permission-update';
|
||||
import { Cage } from '~/types/cage';
|
||||
import { PermissionUpdate } from '~/types/permission-update';
|
||||
|
||||
type PermissionState = Pick<StoreState, "permissions">;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import _ from 'lodash';
|
||||
import { StoreState } from '../../store/type';
|
||||
import { Cage } from '../../types/cage';
|
||||
import { Cage } from '~/types/cage';
|
||||
|
||||
type PublishState = Pick<StoreState, 'notebooks'>;
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
import _ from 'lodash';
|
||||
|
||||
import { PublishUpdate } from '../../types/publish-update';
|
||||
import { Cage } from '../../types/cage';
|
||||
import { PublishUpdate } from '~/types/publish-update';
|
||||
import { Cage } from '~/types/cage';
|
||||
import { StoreState } from '../../store/type';
|
||||
import { getTagFromFrond } from '../../types/noun';
|
||||
import { getTagFromFrond } from '~/types/noun';
|
||||
|
||||
type PublishState = Pick<StoreState, 'notebooks'>;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import _ from 'lodash';
|
||||
import { StoreState } from '../../store/type';
|
||||
import { Cage } from '../../types/cage';
|
||||
import { S3Update } from '../../types/s3-update';
|
||||
import { Cage } from '~/types/cage';
|
||||
import { S3Update } from '~/types/s3-update';
|
||||
|
||||
type S3State = Pick<StoreState, 's3'>;
|
||||
|
||||
|
@ -5,7 +5,7 @@ import LocalReducer from '../reducers/local';
|
||||
import ChatReducer from '../reducers/chat-update';
|
||||
|
||||
import { StoreState } from './type';
|
||||
import { Cage } from '../types/cage';
|
||||
import { Cage } from '~/types/cage';
|
||||
import ContactReducer from '../reducers/contact-update';
|
||||
import LinkUpdateReducer from '../reducers/link-update';
|
||||
import S3Reducer from '../reducers/s3-update';
|
||||
@ -42,6 +42,7 @@ export default class GlobalStore extends BaseStore<StoreState> {
|
||||
connection: 'connected',
|
||||
sidebarShown: true,
|
||||
omniboxShown: false,
|
||||
suspendedFocus: null,
|
||||
baseHash: null,
|
||||
invites: {},
|
||||
associations: {
|
||||
|
@ -1,21 +1,22 @@
|
||||
import { Inbox, Envelope } from '../types/chat-update';
|
||||
import { ChatHookUpdate } from '../types/chat-hook-update';
|
||||
import { Path } from '../types/noun';
|
||||
import { Invites } from '../types/invite-update';
|
||||
import { Associations } from '../types/metadata-update';
|
||||
import { Rolodex } from '../types/contact-update';
|
||||
import { Notebooks } from '../types/publish-update';
|
||||
import { Groups } from '../types/group-update';
|
||||
import { S3State } from '../types/s3-update';
|
||||
import { Permissions } from '../types/permission-update';
|
||||
import { LaunchState, WeatherState } from '../types/launch-update';
|
||||
import { LinkComments, LinkCollections, LinkSeen } from '../types/link-update';
|
||||
import { ConnectionStatus } from '../types/connection';
|
||||
import { Inbox, Envelope } from '~/types/chat-update';
|
||||
import { ChatHookUpdate } from '~/types/chat-hook-update';
|
||||
import { Path } from '~/types/noun';
|
||||
import { Invites } from '~/types/invite-update';
|
||||
import { Associations } from '~/types/metadata-update';
|
||||
import { Rolodex } from '~/types/contact-update';
|
||||
import { Notebooks } from '~/types/publish-update';
|
||||
import { Groups } from '~/types/group-update';
|
||||
import { S3State } from '~/types/s3-update';
|
||||
import { Permissions } from '~/types/permission-update';
|
||||
import { LaunchState, WeatherState } from '~/types/launch-update';
|
||||
import { LinkComments, LinkCollections, LinkSeen } from '~/types/link-update';
|
||||
import { ConnectionStatus } from '~/types/connection';
|
||||
|
||||
export interface StoreState {
|
||||
// local state
|
||||
sidebarShown: boolean;
|
||||
omniboxShown: boolean;
|
||||
suspendedFocus: HTMLInputElement | null;
|
||||
dark: boolean;
|
||||
connection: ConnectionStatus;
|
||||
baseHash: string | null;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import BaseStore from "../store/base";
|
||||
import BaseApi from "../api/base";
|
||||
import { Path } from "../types/noun";
|
||||
import { Path } from "~/types/noun";
|
||||
|
||||
export default class BaseSubscription<S extends object> {
|
||||
private errorCount = 0;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import BaseSubscription from './base';
|
||||
import { StoreState } from '../store/type';
|
||||
import { Path } from '../types/noun';
|
||||
import { Path } from '~/types/noun';
|
||||
import _ from 'lodash';
|
||||
|
||||
|
||||
|
@ -18,11 +18,11 @@ import StatusBar from './components/StatusBar';
|
||||
import Omnibox from './components/Omnibox';
|
||||
import ErrorComponent from './components/Error';
|
||||
|
||||
import GlobalStore from '../logic/store/store';
|
||||
import GlobalSubscription from '../logic/subscription/global';
|
||||
import GlobalApi from '../logic/api/global';
|
||||
import { uxToHex } from '../logic/lib/util';
|
||||
import { Sigil } from '../logic/lib/sigil';
|
||||
import GlobalStore from '~/logic/store/store';
|
||||
import GlobalSubscription from '~/logic/subscription/global';
|
||||
import GlobalApi from '~/logic/api/global';
|
||||
import { uxToHex } from '~/logic/lib/util';
|
||||
import { Sigil } from '~/logic/lib/sigil';
|
||||
|
||||
const Root = styled.div`
|
||||
font-family: ${p => p.theme.fonts.sans};
|
||||
@ -30,6 +30,8 @@ const Root = styled.div`
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
`;
|
||||
|
||||
const StatusBarWithRouter = withRouter(StatusBar);
|
||||
@ -59,6 +61,7 @@ class App extends React.Component {
|
||||
this.api.local.getBaseHash();
|
||||
Mousetrap.bindGlobal(['command+/', 'ctrl+/'], (e) => {
|
||||
e.preventDefault();
|
||||
e.stopImmediatePropagation();
|
||||
this.api.local.setOmnibox();
|
||||
});
|
||||
this.setFavicon();
|
||||
|
@ -11,11 +11,11 @@ import { SettingsScreen } from './components/settings';
|
||||
import { NewScreen } from './components/new';
|
||||
import { JoinScreen } from './components/join';
|
||||
import { NewDmScreen } from './components/new-dm';
|
||||
import { PatpNoSig } from '../../../types/noun';
|
||||
import GlobalApi from '../../logic/api/global';
|
||||
import { StoreState } from '../../logic/store/type';
|
||||
import GlobalSubscription from '../../logic/subscription/global';
|
||||
import {groupBunts} from '../../../types/group-update';
|
||||
import { PatpNoSig } from '~/types/noun';
|
||||
import GlobalApi from '~/logic/api/global';
|
||||
import { StoreState } from '~/logic/store/type';
|
||||
import GlobalSubscription from '~/logic/subscription/global';
|
||||
import {groupBunts} from '~/types/group-update';
|
||||
|
||||
type ChatAppProps = StoreState & {
|
||||
ship: PatpNoSig;
|
||||
|
@ -6,15 +6,15 @@ import { Link, RouteComponentProps } from "react-router-dom";
|
||||
import { ChatWindow } from './lib/chat-window';
|
||||
import { ChatHeader } from './lib/chat-header';
|
||||
import { ChatInput } from "./lib/chat-input";
|
||||
import { deSig } from "../../../../logic/lib/util";
|
||||
import { ChatHookUpdate } from "../../../../types/chat-hook-update";
|
||||
import ChatApi from "../../../../logic/api/chat";
|
||||
import { Inbox, Envelope } from "../../../../types/chat-update";
|
||||
import { Contacts } from "../../../../types/contact-update";
|
||||
import { Path, Patp } from "../../../../types/noun";
|
||||
import GlobalApi from "../../../../logic/api/global";
|
||||
import { Association } from "../../../../types/metadata-update";
|
||||
import {Group} from "../../../../types/group-update";
|
||||
import { deSig } from "~/logic/lib/util";
|
||||
import { ChatHookUpdate } from "~/types/chat-hook-update";
|
||||
import ChatApi from "~/logic/api/chat";
|
||||
import { Inbox, Envelope } from "~/types/chat-update";
|
||||
import { Contacts } from "~/types/contact-update";
|
||||
import { Path, Patp } from "~/types/noun";
|
||||
import GlobalApi from "~/logic/api/global";
|
||||
import { Association } from "~/types/metadata-update";
|
||||
import {Group} from "~/types/group-update";
|
||||
|
||||
|
||||
type ChatScreenProps = RouteComponentProps<{
|
||||
|
@ -2,145 +2,99 @@ import React, { Component } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ const MARKDOWN_CONFIG = {
|
||||
name: 'markdown',
|
||||
tokenTypeOverrides: {
|
||||
header: 'presentation',
|
||||
quote: 'presentation',
|
||||
quote: 'quote',
|
||||
list1: 'presentation',
|
||||
list2: 'presentation',
|
||||
list3: 'presentation',
|
||||
@ -121,16 +121,18 @@ export default class ChatEditor extends Component {
|
||||
|
||||
return (
|
||||
<div
|
||||
className="chat fr h-100 flex bg-gray0-d lh-copy pl2 w-100 items-center"
|
||||
style={{ flexGrow: 1, maxHeight: '224px', width: 'calc(100% - 72px)' }}
|
||||
>
|
||||
className={
|
||||
'chat fr h-100 flex bg-gray0-d lh-copy pl2 w-100 items-center' +
|
||||
(props.inCodeMode ? ' code' : '')
|
||||
}
|
||||
style={{ flexGrow: 1, maxHeight: '224px', width: 'calc(100% - 72px)' }}>
|
||||
<CodeEditor
|
||||
value={props.message}
|
||||
options={options}
|
||||
onChange={(e, d, v) => this.messageChange(e, d, v)}
|
||||
editorDidMount={(editor) => {
|
||||
this.editor = editor;
|
||||
if (!(BROWSER_REGEX.test(navigator.userAgent))) {
|
||||
if (!BROWSER_REGEX.test(navigator.userAgent)) {
|
||||
editor.focus();
|
||||
}
|
||||
}}
|
||||
|
@ -2,8 +2,8 @@ import React, { Component, Fragment } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
import { ChatTabBar } from "./chat-tabbar";
|
||||
import { SidebarSwitcher } from "../../../../components/SidebarSwitch";
|
||||
import { deSig } from "../../../../../logic/lib/util";
|
||||
import { SidebarSwitcher } from "~/views/components/SidebarSwitch";
|
||||
import { deSig } from "~/logic/lib/util";
|
||||
|
||||
|
||||
export const ChatHeader = (props) => {
|
||||
|
@ -2,8 +2,8 @@ import React, { Component } from 'react';
|
||||
import ChatEditor from './chat-editor';
|
||||
import { S3Upload } from './s3-upload'
|
||||
;
|
||||
import { uxToHex } from '../../../../../logic/lib/util';
|
||||
import { Sigil } from '../../../../../logic/lib/sigil';
|
||||
import { uxToHex } from '~/logic/lib/util';
|
||||
import { Sigil } from '~/logic/lib/sigil';
|
||||
|
||||
|
||||
const URL_REGEX = new RegExp(String(/^((\w+:\/\/)[-a-zA-Z0-9:@;?&=\/%\+\.\*!'\(\),\$_\{\}\^~\[\]`#|]+)/.source));
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { Component, Fragment } from "react";
|
||||
|
||||
import { scrollIsAtTop, scrollIsAtBottom } from "../../../../../logic/lib/util";
|
||||
import { scrollIsAtTop, scrollIsAtBottom } from "~/logic/lib/util";
|
||||
|
||||
// Restore chat position on FF when new messages come in
|
||||
const recalculateScrollTop = (lastScrollHeight, scrollContainer) => {
|
||||
|
@ -11,14 +11,14 @@ export default class CodeContent extends Component {
|
||||
(Boolean(content.code.output) &&
|
||||
content.code.output.length && content.code.output.length > 0) ?
|
||||
(
|
||||
<pre className={`f7 clamp-attachment pa1 mt0 mb0 b--gray4 b--gray1-d bl br bb`}>
|
||||
<pre className={`code f7 clamp-attachment pa1 mt0 mb0`}>
|
||||
{content.code.output[0].join('\n')}
|
||||
</pre>
|
||||
) : null;
|
||||
|
||||
|
||||
return (
|
||||
<div className="mv2">
|
||||
<pre className={`f7 clamp-attachment pa1 mt0 mb0 bg-light-gray b--gray4 b--gray1-d ba`}>
|
||||
<pre className={`code f7 clamp-attachment pa1 mt0 mb0`}>
|
||||
{content.code.expression}
|
||||
</pre>
|
||||
{outputElement}
|
||||
|
@ -6,7 +6,6 @@ import urbitOb from 'urbit-ob';
|
||||
|
||||
const DISABLED_BLOCK_TOKENS = [
|
||||
'indentedCode',
|
||||
'blockquote',
|
||||
'atxHeading',
|
||||
'thematicBreak',
|
||||
'list',
|
||||
@ -41,7 +40,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?
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Button } from '@tlon/indigo-react';
|
||||
|
||||
const IMAGE_REGEX = new RegExp(/(jpg|img|png|gif|tiff|jpeg|webp|webm|svg)$/i);
|
||||
|
||||
@ -79,11 +80,14 @@ export default class UrlContent extends Component {
|
||||
>
|
||||
{content.url}
|
||||
</a>
|
||||
<a className="bs ml2 f7 pointer lh-copy v-top"
|
||||
onClick={e => this.unfoldEmbed()}
|
||||
<Button
|
||||
border={1}
|
||||
style={{ display: 'inline-flex', height: '1.66em' }} // Height is hacked to line-height until Button supports proper size
|
||||
ml={1}
|
||||
onClick={e => this.unfoldEmbed()}
|
||||
>
|
||||
[embed]
|
||||
</a>
|
||||
{this.state.unfold ? 'collapse' : 'embed'}
|
||||
</Button>
|
||||
{contents}
|
||||
</div>
|
||||
);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { Component } from 'react';
|
||||
import Toggle from '../../../../components/toggle';
|
||||
import { InviteSearch } from '../../../../components/InviteSearch';
|
||||
import Toggle from '~/views/components/toggle';
|
||||
import { InviteSearch } from '~/views/components/InviteSearch';
|
||||
|
||||
|
||||
export class GroupifyButton extends Component {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { Component } from 'react';
|
||||
import { InviteSearch } from '../../../../components/InviteSearch';
|
||||
import { Spinner } from '../../../../components/Spinner';
|
||||
import { InviteSearch } from '~/views/components/InviteSearch';
|
||||
import { Spinner } from '~/views/components/Spinner';
|
||||
|
||||
export class InviteElement extends Component {
|
||||
constructor(props) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { Component } from 'react';
|
||||
import { OverlaySigil } from './overlay-sigil';
|
||||
import MessageContent from './message-content';
|
||||
import { uxToHex, cite, writeText } from '../../../../../logic/lib/util';
|
||||
import { uxToHex, cite, writeText } from '~/logic/lib/util';
|
||||
import moment from 'moment';
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import { uxToHex } from '../../../../../logic/lib/util';
|
||||
import { uxToHex } from '~/logic/lib/util';
|
||||
|
||||
|
||||
export class MetadataColor extends Component {
|
||||
|
@ -2,7 +2,7 @@ import React, { Component } from 'react';
|
||||
|
||||
import { MetadataColor } from './metadata-color';
|
||||
import { MetadataInput } from './metadata-input';
|
||||
import { uxToHex } from '../../../../../logic/lib/util';
|
||||
import { uxToHex } from '~/logic/lib/util';
|
||||
|
||||
|
||||
export const MetadataSettings = (props) => {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Sigil } from '../../../../../logic/lib/sigil';
|
||||
import { Sigil } from '~/logic/lib/sigil';
|
||||
import {
|
||||
ProfileOverlay,
|
||||
OVERLAY_HEIGHT
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { cite } from '../../../../../logic/lib/util';
|
||||
import { Sigil } from '../../../../../logic/lib/sigil';
|
||||
import { cite } from '~/logic/lib/util';
|
||||
import { Sigil } from '~/logic/lib/sigil';
|
||||
|
||||
export const OVERLAY_HEIGHT = 250;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { Component } from 'react';
|
||||
import S3Client from '../../../../../logic/lib/s3';
|
||||
import S3Client from '~/logic/lib/s3';
|
||||
|
||||
export class S3Upload extends Component {
|
||||
constructor(props) {
|
||||
|
@ -1,9 +1,9 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Spinner } from '../../../components/Spinner';
|
||||
import { Spinner } from '~/views/components/Spinner';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { InviteSearch } from '../../../components/InviteSearch';
|
||||
import { InviteSearch } from '~/views/components/InviteSearch';
|
||||
import urbitOb from 'urbit-ob';
|
||||
import { deSig } from '../../../../logic/lib/util';
|
||||
import { deSig } from '~/logic/lib/util';
|
||||
|
||||
export class NewDmScreen extends Component {
|
||||
constructor(props) {
|
||||
|
@ -1,8 +1,8 @@
|
||||
import React, { Component } from 'react';
|
||||
import { InviteSearch } from '../../../components/InviteSearch';
|
||||
import { Spinner } from '../../../components/Spinner';
|
||||
import { InviteSearch } from '~/views/components/InviteSearch';
|
||||
import { Spinner } from '~/views/components/Spinner';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { deSig } from '../../../../logic/lib/util';
|
||||
import { deSig } from '~/logic/lib/util';
|
||||
|
||||
export class NewScreen extends Component {
|
||||
constructor(props) {
|
||||
|
@ -1,14 +1,14 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { deSig } from '../../../../logic/lib/util';
|
||||
import { deSig } from '~/logic/lib/util';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import { ChatHeader } from './lib/chat-header';
|
||||
import { MetadataSettings } from './lib/metadata-settings';
|
||||
import { DeleteButton } from './lib/delete-button';
|
||||
import { GroupifyButton } from './lib/groupify-button';
|
||||
import { Spinner } from '../../../components/Spinner';
|
||||
import { Spinner } from '~/views/components/Spinner';
|
||||
import { ChatTabBar } from './lib/chat-tabbar';
|
||||
import SidebarSwitcher from '../../../components/SidebarSwitch';
|
||||
import SidebarSwitcher from '~/views/components/SidebarSwitch';
|
||||
|
||||
|
||||
export class SettingsScreen extends Component {
|
||||
|
@ -1,8 +1,8 @@
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import Welcome from './lib/welcome';
|
||||
import { alphabetiseAssociations } from '../../../../logic/lib/util';
|
||||
import SidebarInvite from '../../../components/SidebarInvite';
|
||||
import { alphabetiseAssociations } from '~/logic/lib/util';
|
||||
import SidebarInvite from '~/views/components/SidebarInvite';
|
||||
import { GroupItem } from './lib/group-item';
|
||||
|
||||
export class Sidebar extends Component {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { Component } from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { Link } from 'react-router-dom';
|
||||
import ErrorBoundary from '../../../components/ErrorBoundary';
|
||||
import ErrorBoundary from '~/views/components/ErrorBoundary';
|
||||
|
||||
export class Skeleton extends Component {
|
||||
render() {
|
||||
|
@ -256,9 +256,16 @@ blockquote {
|
||||
font-family: 'Inter';
|
||||
}
|
||||
|
||||
.chat .CodeMirror.cm-s-code.chat .cm-s-tlon * {
|
||||
font-family: 'Source Code Pro';
|
||||
code, pre.code {
|
||||
background-color: var(--light-gray);
|
||||
}
|
||||
|
||||
code, .code, .chat.code .react-codemirror2 .CodeMirror * {
|
||||
font-family: 'Source Code Pro';
|
||||
}
|
||||
|
||||
.chat .CodeMirror.cm-s-code.chat * {
|
||||
font-family: 'Source Code Pro';
|
||||
}
|
||||
|
||||
.chat .CodeMirror-selected { background:#BAE3FE !important; color: black; }
|
||||
@ -267,6 +274,7 @@ pre.CodeMirror-placeholder.CodeMirror-line-like { color: var(--gray); }
|
||||
.chat .cm-s-tlon span { font-family: "Inter"}
|
||||
.chat .cm-s-tlon span.cm-meta { color: var(--gray); }
|
||||
.chat .cm-s-tlon span.cm-number { color: var(--gray); }
|
||||
.chat .cm-s-tlon span.cm-quote { color: var(--gray); }
|
||||
.chat .cm-s-tlon span.cm-keyword { line-height: 1em; font-weight: bold; color: var(--gray); }
|
||||
.chat .cm-s-tlon span.cm-atom { font-weight: bold; color: var(--gray); }
|
||||
.chat .cm-s-tlon span.cm-def { color: black; }
|
||||
|
@ -48,7 +48,7 @@ export default class DojoApp extends Component {
|
||||
return (
|
||||
<div
|
||||
className="bg-white bg-gray0-d"
|
||||
style={{ height: 'calc(100vh - 45px)' }}
|
||||
style={{ height: '100%' }}
|
||||
>
|
||||
<Route
|
||||
exact
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { Component } from 'react';
|
||||
import { cite } from '../../../../logic/lib/util';
|
||||
import { Spinner } from '../../../components/Spinner';
|
||||
import { cite } from '~/logic/lib/util';
|
||||
import { Spinner } from '~/views/components/Spinner';
|
||||
|
||||
export class Input extends Component {
|
||||
constructor(props) {
|
||||
@ -14,10 +14,16 @@ export class Input extends Component {
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
if (
|
||||
!document.activeElement == document.body
|
||||
|| document.activeElement == this.inputRef.current
|
||||
) {
|
||||
this.inputRef.current.focus();
|
||||
this.inputRef.current.setSelectionRange(this.props.cursor, this.props.cursor);
|
||||
}
|
||||
}
|
||||
|
||||
keyPress = (e) => {
|
||||
keyPress(e) {
|
||||
if ((e.getModifierState('Control') || event.getModifierState('Meta'))
|
||||
&& e.key === 'v') {
|
||||
return;
|
||||
@ -33,75 +39,79 @@ export class Input extends Component {
|
||||
return;
|
||||
}
|
||||
|
||||
// submit on enter
|
||||
if (e.key === 'Enter') {
|
||||
this.setState({ awaiting: true, type: 'Sending to Dojo' });
|
||||
this.props.api.soto('ret').then(() => {
|
||||
this.setState({ awaiting: false });
|
||||
});
|
||||
} else if ((e.key === 'Backspace') && (this.props.cursor > 0)) {
|
||||
this.props.store.doEdit({ del: this.props.cursor - 1 });
|
||||
return this.props.store.setState({ cursor: this.props.cursor - 1 });
|
||||
} else if (e.key === 'Backspace') {
|
||||
return;
|
||||
} else if (e.key.startsWith('Arrow')) {
|
||||
if (e.key === 'ArrowLeft') {
|
||||
if (this.props.cursor > 0) {
|
||||
this.props.store.setState({ cursor: this.props.cursor - 1 });
|
||||
}
|
||||
} else if (e.key === 'ArrowRight') {
|
||||
if (this.props.cursor < this.props.input.length) {
|
||||
this.props.store.setState({ cursor: this.props.cursor + 1 });
|
||||
// submit on enter
|
||||
if (e.key === 'Enter') {
|
||||
this.setState({ awaiting: true, type: 'Sending to Dojo' });
|
||||
this.props.api.soto('ret').then(() => {
|
||||
this.setState({ awaiting: false });
|
||||
});
|
||||
} else if ((e.key === 'Backspace') && (this.props.cursor > 0)) {
|
||||
this.props.store.doEdit({ del: this.props.cursor - 1 });
|
||||
return this.props.store.setState({ cursor: this.props.cursor - 1 });
|
||||
} else if (e.key === 'Backspace') {
|
||||
return;
|
||||
} else if (e.key.startsWith('Arrow')) {
|
||||
if (e.key === 'ArrowLeft') {
|
||||
if (this.props.cursor > 0) {
|
||||
this.props.store.setState({ cursor: this.props.cursor - 1 });
|
||||
}
|
||||
} else if (e.key === 'ArrowRight') {
|
||||
if (this.props.cursor < this.props.input.length) {
|
||||
this.props.store.setState({ cursor: this.props.cursor + 1 });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// tab completion
|
||||
else if (e.key === 'Tab') {
|
||||
this.setState({ awaiting: true, type: 'Getting suggestions' });
|
||||
this.props.api.soto({ tab: this.props.cursor }).then(() => {
|
||||
this.setState({ awaiting: false });
|
||||
});
|
||||
}
|
||||
|
||||
// capture and transmit most characters
|
||||
else {
|
||||
this.props.store.doEdit({ ins: { cha: e.key, at: this.props.cursor } });
|
||||
this.props.store.setState({ cursor: this.props.cursor + 1 });
|
||||
}
|
||||
}
|
||||
|
||||
// tab completion
|
||||
else if (e.key === 'Tab') {
|
||||
this.setState({ awaiting: true, type: 'Getting suggestions' });
|
||||
this.props.api.soto({ tab: this.props.cursor }).then(() => {
|
||||
this.setState({ awaiting: false });
|
||||
});
|
||||
}
|
||||
|
||||
// capture and transmit most characters
|
||||
else {
|
||||
this.props.store.doEdit({ ins: { cha: e.key, at: this.props.cursor } });
|
||||
this.props.store.setState({ cursor: this.props.cursor + 1 });
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="flex flex-row flex-grow-1 relative">
|
||||
<div className="flex-shrink-0">{cite(this.props.ship)}:dojo
|
||||
render() {
|
||||
return (
|
||||
<div className="flex flex-row flex-grow-1 relative">
|
||||
<div className="flex-shrink-0"><span class="dn-s">{cite(this.props.ship)}:</span>dojo
|
||||
</div>
|
||||
<span id="prompt">
|
||||
{this.props.prompt}
|
||||
</span>
|
||||
<input
|
||||
autoFocus
|
||||
autocorrect="off"
|
||||
autocapitalize="off"
|
||||
spellcheck="false"
|
||||
tabindex="0"
|
||||
wrap="off"
|
||||
className="mono ml1 flex-auto dib w-100"
|
||||
id="dojo"
|
||||
cursor={this.props.cursor}
|
||||
onClick={e => this.props.store.setState({ cursor: e.target.selectionEnd })}
|
||||
onKeyDown={this.keyPress}
|
||||
onPaste={(e) => {
|
||||
const clipboardData = e.clipboardData || window.clipboardData;
|
||||
const paste = Array.from(clipboardData.getData('Text'));
|
||||
paste.reduce(async (previous, next) => {
|
||||
await previous;
|
||||
this.setState({ cursor: this.props.cursor + 1 });
|
||||
return this.props.store.doEdit({ ins: { cha: next, at: this.props.cursor } });
|
||||
}, Promise.resolve());
|
||||
e.preventDefault();
|
||||
}}
|
||||
ref={this.inputRef}
|
||||
defaultValue={this.props.input}
|
||||
/>
|
||||
<Spinner awaiting={this.state.awaiting} text={`${this.state.type}...`} classes="absolute right-0 bottom-0 inter pa ba pa2 b--gray1-d" />
|
||||
</div>
|
||||
<span id="prompt">
|
||||
{this.props.prompt}
|
||||
</span>
|
||||
<input
|
||||
autoCorrect="false"
|
||||
autoFocus={true}
|
||||
className="mono ml1 flex-auto dib w-100"
|
||||
id="dojo"
|
||||
cursor={this.props.cursor}
|
||||
onClick={e => this.props.store.setState({ cursor: e.target.selectionEnd })}
|
||||
onKeyDown={this.keyPress}
|
||||
onPaste={(e) => {
|
||||
const clipboardData = e.clipboardData || window.clipboardData;
|
||||
const paste = Array.from(clipboardData.getData('Text'));
|
||||
paste.reduce(async (previous, next) => {
|
||||
await previous;
|
||||
this.setState({ cursor: this.props.cursor + 1 });
|
||||
return this.props.store.doEdit({ ins: { cha: next, at: this.props.cursor } });
|
||||
}, Promise.resolve());
|
||||
e.preventDefault();
|
||||
}}
|
||||
ref={this.inputRef}
|
||||
defaultValue={this.props.input}
|
||||
/>
|
||||
<Spinner awaiting={this.state.awaiting} text={`${this.state.type}...`} classes="absolute right-0 bottom-0 inter pa ba pa2 b--gray1-d" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -11,10 +11,10 @@ import { AddScreen } from './components/lib/add-contact';
|
||||
import { JoinScreen } from './components/join';
|
||||
import GroupDetail from './components/lib/group-detail';
|
||||
|
||||
import { PatpNoSig } from '../../../types/noun';
|
||||
import GlobalApi from '../../../logic/api/global';
|
||||
import { StoreState } from '../../../logic/store/type';
|
||||
import GlobalSubscription from '../../../logic/subscription/global';
|
||||
import { PatpNoSig } from '~/types/noun';
|
||||
import GlobalApi from '~/logic/api/global';
|
||||
import { StoreState } from '~/logic/store/type';
|
||||
import GlobalSubscription from '~/logic/subscription/global';
|
||||
|
||||
|
||||
type GroupsAppProps = StoreState & {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Spinner } from '../../../components/Spinner';
|
||||
import { Spinner } from '~/views/components/Spinner';
|
||||
import urbitOb from 'urbit-ob';
|
||||
|
||||
export class JoinScreen extends Component {
|
||||
|
@ -1,12 +1,12 @@
|
||||
import React, { Component } from 'react';
|
||||
import _ from 'lodash';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { InviteSearch, Invites } from '../../../../components/InviteSearch';
|
||||
import { Spinner } from '../../../../components/Spinner';
|
||||
import { InviteSearch, Invites } from '~/views/components/InviteSearch';
|
||||
import { Spinner } from '~/views/components/Spinner';
|
||||
import { uuid } from '../../../../lib/util';
|
||||
import { Groups } from '../../../../types/group-update';
|
||||
import { Rolodex } from '../../../../types/contact-update';
|
||||
import { Path } from '../../../../types/noun';
|
||||
import { Groups } from '~/types/group-update';
|
||||
import { Rolodex } from '~/types/contact-update';
|
||||
import { Path } from '~/types/noun';
|
||||
import GlobalApi from '../../../../api/global';
|
||||
import { History } from 'history';
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Sigil } from '../../../../../logic/lib/sigil';
|
||||
import { Sigil } from '~/logic/lib/sigil';
|
||||
|
||||
import { Link } from 'react-router-dom';
|
||||
import { EditElement } from './edit-element';
|
||||
import { Spinner } from '../../../../components/Spinner';
|
||||
import { uxToHex } from '../../../../../logic/lib/util';
|
||||
import { Spinner } from '~/views/components/Spinner';
|
||||
import { uxToHex } from '~/logic/lib/util';
|
||||
import { S3Upload } from './s3-upload';
|
||||
|
||||
export class ContactCard extends Component {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Sigil } from '../../../../../logic/lib/sigil';
|
||||
import { uxToHex, cite } from '../../../../../logic/lib/util';
|
||||
import { Sigil } from '~/logic/lib/sigil';
|
||||
import { uxToHex, cite } from '~/logic/lib/util';
|
||||
|
||||
export class ContactItem extends Component {
|
||||
render() {
|
||||
|
@ -4,14 +4,14 @@ import { FixedSizeList as List } from 'react-window';
|
||||
|
||||
import { ContactItem } from './contact-item';
|
||||
import { ShareSheet } from './share-sheet';
|
||||
import { Sigil } from '../../../../../logic/lib/sigil';
|
||||
import { Spinner } from '../../../../components/Spinner';
|
||||
import { cite } from '../../../../../logic/lib/util';
|
||||
import { roleForShip, resourceFromPath } from '../../../../../logic/lib/group';
|
||||
import { Path, PatpNoSig } from '../../../../../types/noun';
|
||||
import { Rolodex, Contacts, Contact } from '../../../../../types/contact-update';
|
||||
import { Groups, Group } from '../../../../../types/group-update';
|
||||
import GlobalApi from '../../../../../logic/api/global';
|
||||
import { Sigil } from '~/logic/lib/sigil';
|
||||
import { Spinner } from '~/views/components/Spinner';
|
||||
import { cite } from '~/logic/lib/util';
|
||||
import { roleForShip, resourceFromPath } from '~/logic/lib/group';
|
||||
import { Path, PatpNoSig } from '~/types/noun';
|
||||
import { Rolodex, Contacts, Contact } from '~/types/contact-update';
|
||||
import { Groups, Group } from '~/types/group-update';
|
||||
import GlobalApi from '~/logic/api/global';
|
||||
|
||||
interface ContactSidebarProps {
|
||||
activeDrawer: 'contacts' | 'detail' | 'rightPanel';
|
||||
|
@ -1,11 +1,11 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Spinner } from '../../../../components/Spinner';
|
||||
import { Toggle } from '../../../../components/toggle';
|
||||
import { GroupView } from '../../../../components/Group';
|
||||
import { Spinner } from '~/views/components/Spinner';
|
||||
import { Toggle } from '~/views/components/toggle';
|
||||
import { GroupView } from '~/views/components/Group';
|
||||
|
||||
import { deSig, uxToHex, writeText } from '../../../../../logic/lib/util';
|
||||
import { roleForShip, resourceFromPath } from '../../../../../logic/lib/group';
|
||||
import { deSig, uxToHex, writeText } from '~/logic/lib/util';
|
||||
import { roleForShip, resourceFromPath } from '~/logic/lib/group';
|
||||
|
||||
export class GroupDetail extends Component {
|
||||
constructor(props) {
|
||||
@ -19,6 +19,7 @@ export class GroupDetail extends Component {
|
||||
this.changeTitle = this.changeTitle.bind(this);
|
||||
this.changeDescription = this.changeDescription.bind(this);
|
||||
this.changePolicy = this.changePolicy.bind(this);
|
||||
this.getShortcode = this.getShortcode.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@ -185,6 +186,41 @@ export class GroupDetail extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
getShortcode(group, path) {
|
||||
if (group?.policy?.open) {
|
||||
return (
|
||||
<div className='mt4'>
|
||||
<p className='f9 mt4 lh-copy'>Share</p>
|
||||
<p className='f9 gray2 mb2'>
|
||||
Share a shortcode to join this group
|
||||
</p>
|
||||
<div
|
||||
className='relative w-100 flex'
|
||||
style={{ maxWidth: '29rem' }}>
|
||||
<input
|
||||
className={'f8 mono ba b--gray3 b--gray2-d bg-gray0-d ' +
|
||||
'white-d pa3 db w-100 flex-auto mr3 pr9'}
|
||||
disabled={true}
|
||||
value={path.substr(6)}
|
||||
/>
|
||||
<span
|
||||
className='lh-solid f8 pointer absolute pa3 inter'
|
||||
style={{ right: 12, top: 1 }}
|
||||
ref='copy'
|
||||
onClick={() => {
|
||||
writeText(path.substr(6));
|
||||
this.refs.copy.innerText = 'Copied';
|
||||
}}>
|
||||
Copy
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return <div />;
|
||||
};
|
||||
}
|
||||
|
||||
renderSettings() {
|
||||
const { props } = this;
|
||||
|
||||
@ -201,33 +237,8 @@ export class GroupDetail extends Component {
|
||||
{ description: 'Janitor', tag: 'janitor', addDescription: 'Make Janitor' }
|
||||
];
|
||||
|
||||
let shortcode = <div />;
|
||||
const shortcode = this.getShortcode(group, props.path);
|
||||
|
||||
if (group?.policy?.open) {
|
||||
shortcode = <div className="mt4">
|
||||
<p className="f9 mt4 lh-copy">Share</p>
|
||||
<p className="f9 gray2 mb2">Share a shortcode to join this group</p>
|
||||
<div className="relative w-100 flex"
|
||||
style={{ maxWidth: '29rem' }}
|
||||
>
|
||||
<input
|
||||
className="f8 mono ba b--gray3 b--gray2-d bg-gray0-d white-d pa3 db w-100 flex-auto mr3"
|
||||
disabled={true}
|
||||
value={props.path.substr(6)}
|
||||
/>
|
||||
<span className="lh-solid f8 pointer absolute pa3 inter"
|
||||
style={{ right: 12, top: 1 }}
|
||||
ref="copy"
|
||||
onClick={() => {
|
||||
writeText(props.path.substr(6));
|
||||
this.refs.copy.innerText = 'Copied';
|
||||
}}
|
||||
>
|
||||
Copy
|
||||
</span>
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
return (
|
||||
<div className="pa4 w-100 h-100 white-d overflow-y-auto">
|
||||
<div className="f8 f9-m f9-l f9-xl w-100">
|
||||
|
@ -2,11 +2,11 @@ import React, { Component } from 'react';
|
||||
|
||||
import { Link } from 'react-router-dom';
|
||||
import { GroupItem } from './group-item';
|
||||
import SidebarInvite from '../../../../components/SidebarInvite';
|
||||
import SidebarInvite from '~/views/components/SidebarInvite';
|
||||
import { Welcome } from './welcome';
|
||||
|
||||
import { cite } from '../../../../../logic/lib/util';
|
||||
import { Sigil } from '../../../../../logic/lib/sigil';
|
||||
import { cite } from '~/logic/lib/util';
|
||||
import { Sigil } from '~/logic/lib/sigil';
|
||||
|
||||
|
||||
export class GroupSidebar extends Component {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { Component } from 'react'
|
||||
import S3Client from '../../../../../logic/lib/s3';
|
||||
import S3Client from '~/logic/lib/s3';
|
||||
|
||||
export class S3Upload extends Component {
|
||||
|
||||
|
@ -1,15 +1,15 @@
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import { Link } from 'react-router-dom';
|
||||
import { InviteSearch, Invites } from '../../../components/InviteSearch';
|
||||
import { Spinner } from '../../../components/Spinner';
|
||||
import { Toggle } from '../../../components/toggle';
|
||||
import { InviteSearch, Invites } from '~/views/components/InviteSearch';
|
||||
import { Spinner } from '~/views/components/Spinner';
|
||||
import { Toggle } from '~/views/components/toggle';
|
||||
import { RouteComponentProps } from 'react-router-dom';
|
||||
|
||||
import { Groups, GroupPolicy, Resource } from '../../../../types/group-update';
|
||||
import { Contacts, Rolodex } from '../../../../types/contact-update';
|
||||
import GlobalApi from '../../../../logic/api/global';
|
||||
import { Patp, PatpNoSig, Enc } from '../../../../types/noun';
|
||||
import { Groups, GroupPolicy, Resource } from '~/types/group-update';
|
||||
import { Contacts, Rolodex } from '~/types/contact-update';
|
||||
import GlobalApi from '~/logic/api/global';
|
||||
import { Patp, PatpNoSig, Enc } from '~/types/noun';
|
||||
|
||||
type NewScreenProps = Pick<RouteComponentProps, 'history'> & {
|
||||
groups: Groups;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { Component } from 'react';
|
||||
import { GroupSidebar } from './lib/group-sidebar';
|
||||
import ErrorBoundary from '../../../components/ErrorBoundary';
|
||||
import ErrorBoundary from '~/views/components/ErrorBoundary';
|
||||
|
||||
export class Skeleton extends Component {
|
||||
render() {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { Link } from 'react-router-dom';
|
||||
import defaultApps from '../../../../../logic/lib/default-apps';
|
||||
import defaultApps from '~/logic/lib/default-apps';
|
||||
|
||||
import Tile from './tile';
|
||||
|
||||
|
@ -15,7 +15,7 @@ import {
|
||||
makeRoutePath,
|
||||
amOwnerOfGroup,
|
||||
base64urlDecode
|
||||
} from '../../../logic/lib/util';
|
||||
} from '~/logic/lib/util';
|
||||
|
||||
export class LinksApp extends Component {
|
||||
constructor(props) {
|
||||
|
@ -2,9 +2,9 @@ import React, { Component } from 'react';
|
||||
|
||||
import { Link } from 'react-router-dom';
|
||||
import { GroupItem } from './group-item';
|
||||
import SidebarInvite from '../../../../components/SidebarInvite';
|
||||
import SidebarInvite from '~/views/components/SidebarInvite';
|
||||
import { Welcome } from './welcome';
|
||||
import { alphabetiseAssociations } from '../../../../../logic/lib/util';
|
||||
import { alphabetiseAssociations } from '~/logic/lib/util';
|
||||
|
||||
export class ChannelsSidebar extends Component {
|
||||
// drawer to the left
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { makeRoutePath } from '../../../../../logic/lib/util';
|
||||
import { makeRoutePath } from '~/logic/lib/util';
|
||||
|
||||
export class ChannelsItem extends Component {
|
||||
render() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Sigil } from '../../../../../logic/lib/sigil';
|
||||
import { cite } from '../../../../../logic/lib/util';
|
||||
import { Sigil } from '~/logic/lib/sigil';
|
||||
import { cite } from '~/logic/lib/util';
|
||||
import moment from 'moment';
|
||||
import { Box, Text, Row } from '@tlon/indigo-react';
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { makeRoutePath } from '../../../../../logic/lib/util';
|
||||
import { makeRoutePath } from '~/logic/lib/util';
|
||||
|
||||
export class CommentsPagination extends Component {
|
||||
render() {
|
||||
|
@ -2,7 +2,7 @@ import React, { Component } from 'react';
|
||||
import { CommentItem } from './comment-item';
|
||||
import { CommentsPagination } from './comments-pagination';
|
||||
|
||||
import { getContactDetails } from '../../../../../logic/lib/util';
|
||||
import { getContactDetails } from '~/logic/lib/util';
|
||||
export class Comments extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { Component } from 'react';
|
||||
import { cite } from '../../../../../logic/lib/util';
|
||||
import { cite } from '~/logic/lib/util';
|
||||
import moment from 'moment';
|
||||
|
||||
export class LinkPreview extends Component {
|
||||
|
@ -1,9 +1,9 @@
|
||||
import React, { Component } from 'react';
|
||||
import moment from 'moment';
|
||||
|
||||
import { Sigil } from '../../../../../logic/lib/sigil';
|
||||
import { Sigil } from '~/logic/lib/sigil';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { makeRoutePath, cite } from '../../../../../logic/lib/util';
|
||||
import { makeRoutePath, cite } from '~/logic/lib/util';
|
||||
|
||||
export class LinkItem extends Component {
|
||||
constructor(props) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Spinner } from '../../../../components/Spinner';
|
||||
import { Spinner } from '~/views/components/Spinner';
|
||||
|
||||
export class LinkSubmit extends Component {
|
||||
constructor() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { makeRoutePath } from '../../../../../logic/lib/util';
|
||||
import { makeRoutePath } from '~/logic/lib/util';
|
||||
|
||||
export class LinksTabBar extends Component {
|
||||
render() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Sigil } from '../../../../../logic/lib/sigil';
|
||||
import { uxToHex, cite } from '../../../../../logic/lib/util';
|
||||
import { Sigil } from '~/logic/lib/sigil';
|
||||
import { uxToHex, cite } from '~/logic/lib/util';
|
||||
export class MemberElement extends Component {
|
||||
onRemove() {
|
||||
const { props } = this;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { makeRoutePath } from '../../../../../logic/lib/util';
|
||||
import { makeRoutePath } from '~/logic/lib/util';
|
||||
|
||||
export class Pagination extends Component {
|
||||
render() {
|
||||
|
@ -1,12 +1,12 @@
|
||||
import React, { Component } from 'react';
|
||||
import { LinksTabBar } from './lib/links-tabbar';
|
||||
import { LinkPreview } from './lib/link-detail-preview';
|
||||
import { SidebarSwitcher } from '../../../components/SidebarSwitch';
|
||||
import { SidebarSwitcher } from '~/views/components/SidebarSwitch';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Comments } from './lib/comments';
|
||||
import { Spinner } from '../../../components/Spinner';
|
||||
import { Spinner } from '~/views/components/Spinner';
|
||||
import { LoadingScreen } from './loading';
|
||||
import { makeRoutePath, getContactDetails } from '../../../../logic/lib/util';
|
||||
import { makeRoutePath, getContactDetails } from '~/logic/lib/util';
|
||||
import CommentItem from './lib/comment-item';
|
||||
|
||||
export class LinkDetail extends Component {
|
||||
|
@ -3,13 +3,13 @@ import React, { Component } from 'react';
|
||||
import { LoadingScreen } from './loading';
|
||||
import { MessageScreen } from './lib/message-screen';
|
||||
import { LinksTabBar } from './lib/links-tabbar';
|
||||
import { SidebarSwitcher } from '../../../components/SidebarSwitch';
|
||||
import { SidebarSwitcher } from '~/views/components/SidebarSwitch';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { LinkItem } from './lib/link-item';
|
||||
import { LinkSubmit } from './lib/link-submit';
|
||||
import { Pagination } from './lib/pagination';
|
||||
|
||||
import { makeRoutePath, getContactDetails } from '../../../../logic/lib/util';
|
||||
import { makeRoutePath, getContactDetails } from '~/logic/lib/util';
|
||||
|
||||
export class Links extends Component {
|
||||
constructor(props) {
|
||||
|
@ -1,8 +1,8 @@
|
||||
import React, { Component } from 'react';
|
||||
import { InviteSearch } from '../../../components/InviteSearch';
|
||||
import { Spinner } from '../../../components/Spinner';
|
||||
import { InviteSearch } from '~/views/components/InviteSearch';
|
||||
import { Spinner } from '~/views/components/Spinner';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { makeRoutePath, deSig } from '../../../../logic/lib/util';
|
||||
import { makeRoutePath, deSig } from '~/logic/lib/util';
|
||||
import urbitOb from 'urbit-ob';
|
||||
|
||||
export class NewScreen extends Component {
|
||||
|
@ -1,12 +1,12 @@
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import { uxToHex, makeRoutePath } from '../../../../logic/lib/util';
|
||||
import { uxToHex, makeRoutePath } from '~/logic/lib/util';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import { LoadingScreen } from './loading';
|
||||
import { Spinner } from '../../../components/Spinner';
|
||||
import { Spinner } from '~/views/components/Spinner';
|
||||
import { LinksTabBar } from './lib/links-tabbar';
|
||||
import SidebarSwitcher from '../../../components/SidebarSwitch';
|
||||
import SidebarSwitcher from '~/views/components/SidebarSwitch';
|
||||
|
||||
export class SettingsScreen extends Component {
|
||||
constructor(props) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { Component } from 'react';
|
||||
import { ChannelsSidebar } from './lib/channel-sidebar';
|
||||
import ErrorBoundary from '../../../components/ErrorBoundary';
|
||||
import ErrorBoundary from '~/views/components/ErrorBoundary';
|
||||
|
||||
export class Skeleton extends Component {
|
||||
render() {
|
||||
|
@ -1,8 +1,8 @@
|
||||
import React, { Component } from 'react';
|
||||
import moment from 'moment';
|
||||
import { Sigil } from '../../../../../logic/lib/sigil';
|
||||
import { Sigil } from '~/logic/lib/sigil';
|
||||
import CommentInput from './comment-input';
|
||||
import { uxToHex, cite } from '../../../../../logic/lib/util';
|
||||
import { uxToHex, cite } from '~/logic/lib/util';
|
||||
|
||||
export class CommentItem extends Component {
|
||||
constructor(props) {
|
||||
|
@ -1,8 +1,8 @@
|
||||
import React, { Component } from 'react';
|
||||
import { CommentItem } from './comment-item';
|
||||
import CommentInput from './comment-input';
|
||||
import { dateToDa } from '../../../../../logic/lib/util';
|
||||
import { Spinner } from '../../../../components/Spinner';
|
||||
import { dateToDa } from '~/logic/lib/util';
|
||||
import { Spinner } from '~/views/components/Spinner';
|
||||
|
||||
export class Comments extends Component {
|
||||
constructor(props) {
|
||||
|
@ -1,9 +1,9 @@
|
||||
import React, { Component } from 'react';
|
||||
import { SidebarSwitcher } from '../../../../components/SidebarSwitch';
|
||||
import { Spinner } from '../../../../components/Spinner';
|
||||
import { SidebarSwitcher } from '~/views/components/SidebarSwitch';
|
||||
import { Spinner } from '~/views/components/Spinner';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Controlled as CodeMirror } from 'react-codemirror2';
|
||||
import { dateToDa } from '../../../../../logic/lib/util';
|
||||
import { dateToDa } from '~/logic/lib/util';
|
||||
|
||||
import 'codemirror/mode/markdown/markdown';
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Spinner } from '../../../../components/Spinner';
|
||||
import { Spinner } from '~/views/components/Spinner';
|
||||
import urbitOb from 'urbit-ob';
|
||||
|
||||
export class JoinScreen extends Component {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user