diff --git a/bin/solid.pill b/bin/solid.pill index 92ee7a071..c5fdae773 100644 --- a/bin/solid.pill +++ b/bin/solid.pill @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f4b93e4d91e42c8444bb22447a0ae7d969ec552ba2d0f4b87a8dd20a41709d4e -size 9345380 +oid sha256:ec58605002fafbe6f3a5988fe1db4bd31e2fd40370b30e96db64a98c8f7da0ea +size 9474412 diff --git a/pkg/arvo/app/contact-push-hook.hoon b/pkg/arvo/app/contact-push-hook.hoon index f65ad18b0..1503b2029 100644 --- a/pkg/arvo/app/contact-push-hook.hoon +++ b/pkg/arvo/app/contact-push-hook.hoon @@ -94,16 +94,18 @@ ++ rolo ^- rolodex:store =/ ugroup (scry-group:grp resource) + =/ =rolodex:store + (scry-for:con rolodex:store /all) %- ~(gas by *rolodex:store) ?~ ugroup - =/ c=(unit contact:store) (get-contact:con our.bowl) + =/ c=(unit contact:store) (~(get by rolodex) our.bowl) ?~ c [our.bowl *contact:store]~ [our.bowl u.c]~ %+ murn ~(tap in (members:grp resource)) |= s=ship ^- (unit [ship contact:store]) - =/ c=(unit contact:store) (get-contact:con s) + =/ c=(unit contact:store) (~(get by rolodex) s) ?~(c ~ `[s u.c]) -- :: diff --git a/pkg/arvo/app/contact-store.hoon b/pkg/arvo/app/contact-store.hoon index d61f9edbd..a7c60110d 100644 --- a/pkg/arvo/app/contact-store.hoon +++ b/pkg/arvo/app/contact-store.hoon @@ -104,10 +104,18 @@ |= [rolo=rolodex:store is-public=?] ^- (quip card _state) =/ our-contact (~(got by rolodex) our.bowl) - =. rolodex (~(uni by rolodex) rolo) - =. rolodex (~(put by rolodex) our.bowl our-contact) - :_ state(rolodex rolodex) - (send-diff [%initial rolodex is-public] %.n) + =/ diff-rolo=rolodex:store + %- ~(gas by *rolodex:store) + %+ skim ~(tap in rolo) + |= [=ship =contact:store] + ?~ local-con=(~(get by rolodex) ship) %.y + (gth last-updated.contact last-updated.u.local-con) + =/ new-rolo=rolodex:store + (~(uni by rolodex) diff-rolo) + =. new-rolo (~(put by new-rolo) our.bowl our-contact) + ?: =(new-rolo rolodex) `state + :_ state(rolodex new-rolo) + (send-diff [%initial new-rolo is-public] %.n) :: ++ handle-add |= [=ship =contact:store] diff --git a/pkg/arvo/app/glob.hoon b/pkg/arvo/app/glob.hoon index 432396ead..1974c3c06 100644 --- a/pkg/arvo/app/glob.hoon +++ b/pkg/arvo/app/glob.hoon @@ -5,7 +5,7 @@ /- glob /+ default-agent, verb, dbug |% -++ hash 0v3.t4lg5.84a6h.2bi2s.ni2p9.32uor +++ hash 0v7.iotki.j1ptb.mk9vm.borai.jfcr1 +$ state-0 [%0 hash=@uv glob=(unit (each glob:glob tid=@ta))] +$ all-states $% state-0 diff --git a/pkg/arvo/app/landscape/index.html b/pkg/arvo/app/landscape/index.html index 258622e72..7871f4ed3 100644 --- a/pkg/arvo/app/landscape/index.html +++ b/pkg/arvo/app/landscape/index.html @@ -24,6 +24,6 @@
- + diff --git a/pkg/interface/src/logic/reducers/contact-update.ts b/pkg/interface/src/logic/reducers/contact-update.ts index 1d2e45e35..21b83a004 100644 --- a/pkg/interface/src/logic/reducers/contact-update.ts +++ b/pkg/interface/src/logic/reducers/contact-update.ts @@ -59,18 +59,16 @@ const edit = (json: ContactUpdate, state: S) => { if (!field) { return; } - const contact = state.contacts?.[ship]; - const value = data['edit-field'][field]; - if(!contact) { - return; - } + const value = data['edit-field'][field]; + if(field === 'add-group') { - contact.groups.push(value); + state.contacts[ship].groups.push(value); } else if (field === 'remove-group') { - contact.groups = contact.groups.filter(g => g !== value); + state.contacts[ship].groups = + state.contacts[ship].groups.filter(g => g !== value); } else { - contact[field] = value; + state.contacts[ship][field] = value; } } }; diff --git a/pkg/interface/src/views/apps/chat/ChatResource.tsx b/pkg/interface/src/views/apps/chat/ChatResource.tsx index 03a887a88..5b2950a92 100644 --- a/pkg/interface/src/views/apps/chat/ChatResource.tsx +++ b/pkg/interface/src/views/apps/chat/ChatResource.tsx @@ -80,52 +80,52 @@ export function ChatResource(props: ChatResourceProps) { }, [station]); const [showBanner, setShowBanner] = useState(false); + const [hasLoadedAllowed, setHasLoadedAllowed] = useState(false); const [recipients, setRecipients] = useState([]); const res = resourceFromPath(groupPath); useEffect(() => { (async () => { - if (!res) { - return; -} - if (!group) { - return; -} - if (group.hidden) { - const members = _.compact(await Promise.all( - Array.from(group.members) - .map((s) => { - const ship = `~${s}`; - if(s === window.ship) { - return Promise.resolve(null); - } - return props.api.contacts.fetchIsAllowed( - `~${window.ship}`, - 'personal', - ship, - true - ).then((isAllowed) => { - return isAllowed ? null : ship; - }); - }) - )); + if (!res) { return; } + if (!group) { return; } + if (group.hidden) { + const members = _.compact(await Promise.all( + Array.from(group.members) + .map(s => { + const ship = `~${s}`; + if(s === window.ship) { + return Promise.resolve(null); + } + return props.api.contacts.fetchIsAllowed( + `~${window.ship}`, + 'personal', + ship, + true + ).then(isAllowed => { + return isAllowed ? null : ship; + }); + }) + )); + + if(members.length > 0) { + setShowBanner(true); + setRecipients(members); + } else { + setShowBanner(false); + } - if(members.length > 0) { - setShowBanner(true); - setRecipients(members); } else { - setShowBanner(false); + const groupShared = await props.api.contacts.fetchIsAllowed( + `~${window.ship}`, + 'personal', + res.ship, + true + ); + setShowBanner(!groupShared); } - } else { - const groupShared = await props.api.contacts.fetchIsAllowed( - `~${window.ship}`, - 'personal', - res.ship, - true - ); - setShowBanner(!groupShared); - } + + setHasLoadedAllowed(true); })(); }, [groupPath]); @@ -153,7 +153,10 @@ export function ChatResource(props: ChatResourceProps) { history={props.history} graph={graph} unreadCount={unreadCount} - contacts={!showBanner ? contacts : modifiedContacts} + contacts={ + (!showBanner && hasLoadedAllowed) ? + contacts : modifiedContacts + } association={props.association} associations={props.associations} groups={props.groups} @@ -168,9 +171,13 @@ export function ChatResource(props: ChatResourceProps) { ref={chatInput} api={props.api} station={station} - ourContact={!showBanner ? ourContact : null} + ourContact={ + (!showBanner && hasLoadedAllowed) ? ourContact : null + } envelopes={[]} - contacts={contacts} + contacts={ + (!showBanner && hasLoadedAllowed) ? contacts : modifiedContacts + } onUnmount={appendUnsent} s3={props.s3} placeholder="Message..." diff --git a/pkg/interface/src/views/apps/chat/css/custom.css b/pkg/interface/src/views/apps/chat/css/custom.css index 85cb51c97..702106082 100644 --- a/pkg/interface/src/views/apps/chat/css/custom.css +++ b/pkg/interface/src/views/apps/chat/css/custom.css @@ -95,16 +95,8 @@ h2 { font-family: "Inter", sans-serif; } -.embed-container { - width: 100%; - height: 14rem; -} - .embed-container iframe { - max-width: 24rem; - width: 100%; - height: 100%; - max-height: 26rem; + max-width: 100%; } .mh-16 { diff --git a/pkg/interface/src/views/apps/profile/components/Profile.tsx b/pkg/interface/src/views/apps/profile/components/Profile.tsx index eccf1ce72..c7ed938e0 100644 --- a/pkg/interface/src/views/apps/profile/components/Profile.tsx +++ b/pkg/interface/src/views/apps/profile/components/Profile.tsx @@ -7,14 +7,15 @@ import { Row, BaseImage, Text -} from '@tlon/indigo-react'; +} from "@tlon/indigo-react"; +import RichText from '~/views/components/RichText' +import useLocalState from "~/logic/state/local"; import { Sigil } from '~/logic/lib/sigil'; import { ViewProfile } from './ViewProfile'; import { EditProfile } from './EditProfile'; import { SetStatusBarModal } from '~/views/components/SetStatusBarModal'; import { uxToHex } from '~/logic/lib/util'; -import useLocalState from '~/logic/state/local'; import { useTutorialModal } from '~/views/components/useTutorialModal'; export function Profile(props: any): ReactElement { @@ -61,8 +62,9 @@ export function Profile(props: any): ReactElement { width="100%" > + {ship === `~${window.ship}` ? ( - + <> - + ) : null} - + {contact?.status ?? ''} + overflow="hidden" display="inline-block" verticalAlign="middle">{contact?.status ?? ""} {cover} diff --git a/pkg/interface/src/views/components/Invite/index.tsx b/pkg/interface/src/views/components/Invite/index.tsx index d198e430e..1ada18e65 100644 --- a/pkg/interface/src/views/components/Invite/index.tsx +++ b/pkg/interface/src/views/components/Invite/index.tsx @@ -59,7 +59,7 @@ export function InviteItem(props: InviteItemProps) { if (props.groups?.[resource]?.hidden) { const { metadata } = associations.graph[resource]; - if (name.startsWith('dm--')) { + if (metadata?.module === 'chat') { history.push(`/~landscape/messages/resource/${metadata.module}${resource}`); } else { history.push(`/~landscape/home/resource/${metadata.module}${resource}`); @@ -122,10 +122,7 @@ export function InviteItem(props: InviteItemProps) { - You are joining a DM with - - {cite('~hastuc-dibtux')} - + Joining direct message... ); diff --git a/pkg/interface/src/views/components/ProfileOverlay.tsx b/pkg/interface/src/views/components/ProfileOverlay.tsx index df1fec01c..0b3167b8e 100644 --- a/pkg/interface/src/views/components/ProfileOverlay.tsx +++ b/pkg/interface/src/views/components/ProfileOverlay.tsx @@ -14,6 +14,7 @@ import { ColProps, Icon } from '@tlon/indigo-react'; +import RichText from './RichText'; import { withLocalState } from '~/logic/state/local'; import { ProfileStatus } from './ProfileStatus'; @@ -133,7 +134,7 @@ class ProfileOverlay extends PureComponent {img} - + ) : ( - + {contact?.status ? contact.status : ''} - + ) } diff --git a/pkg/interface/src/views/components/RichText.js b/pkg/interface/src/views/components/RichText.js index 4b40655f3..1ca377ece 100644 --- a/pkg/interface/src/views/components/RichText.js +++ b/pkg/interface/src/views/components/RichText.js @@ -33,10 +33,10 @@ const RichText = React.memo(({ disableRemoteContent, ...props }) => ( videoShown: false, oembedShown: false } : null; - if (hasProvider(linkProps.href)) { + if (!disableRemoteContent && hasProvider(linkProps.href)) { return ; } - + return {linkProps.children}; }, linkReference: (linkProps) => { diff --git a/pkg/interface/src/views/components/StatusBar.js b/pkg/interface/src/views/components/StatusBar.js index b674354a8..16a2e2666 100644 --- a/pkg/interface/src/views/components/StatusBar.js +++ b/pkg/interface/src/views/components/StatusBar.js @@ -107,7 +107,7 @@ const StatusBar = (props) => { width="auto" alignY="top" alignX="right" - flexShrink={0} + flexShrink={'0'} options={ baseUrl + path; const groupPath = getGroupFromWorkspace(workspace); - const groupContacts = (groupPath && contacts[groupPath]) || undefined; - const rootIdentity = contacts?.['/~/default']?.[window.ship]; + const groupContacts = Object.assign({}, ...Array.from(groups?.[groupPath]?.members ?? []).filter(e => contacts[`~${e}`]).map(e => { + return {[e]: contacts[`~${e}`]}; + })) || {}; + const rootIdentity = contacts?.["/~/default"]?.[window.ship]; const groupAssociation = (groupPath && associations.groups[groupPath]) || undefined; const group = (groupPath && groups[groupPath]) || undefined; diff --git a/pkg/interface/src/views/landscape/components/NewChannel.tsx b/pkg/interface/src/views/landscape/components/NewChannel.tsx index 456029910..b5a74e01c 100644 --- a/pkg/interface/src/views/landscape/components/NewChannel.tsx +++ b/pkg/interface/src/views/landscape/components/NewChannel.tsx @@ -101,7 +101,7 @@ export function NewChannel(props: NewChannelProps & RouteComponentProps): ReactE await waiter(p => Boolean(p?.groups?.[`/ship/~${window.ship}/${resId}`])); } actions.setStatus({ success: null }); - const resourceUrl = parentPath(location.pathname); + const resourceUrl = (location.pathname.includes("/messages")) ? "/~landscape/messages" : parentPath(location.pathname); history.push( `${resourceUrl}/resource/${moduleType}/ship/~${window.ship}/${resId}` ); diff --git a/pkg/interface/src/views/landscape/components/Participants.tsx b/pkg/interface/src/views/landscape/components/Participants.tsx index d39a8bace..16f8e1655 100644 --- a/pkg/interface/src/views/landscape/components/Participants.tsx +++ b/pkg/interface/src/views/landscape/components/Participants.tsx @@ -31,10 +31,12 @@ import GlobalApi from '~/logic/api/global'; import { StatelessAsyncAction } from '~/views/components/StatelessAsyncAction'; import useLocalState from '~/logic/state/local'; -const TruncText = styled(Box)` +const TruncText = styled(Text)` white-space: nowrap; overflow: hidden; text-overflow: ellipsis; + display: inline-block; + min-width: 0; `; type Participant = Contact & { patp: string; pending: boolean }; @@ -55,8 +57,10 @@ function getParticipants(cs: Contacts, group: Group) { patp, pending: false })); - const members: Participant[] = _.map(Array.from(group.members), m => - emptyContact(m, false) + const members: Participant[] = _.map( + Array.from(group.members) + .filter(e => group?.policy?.invite?.pending ? !group.policy.invite.pending.has(e) : true), m => + emptyContact(m, false) ); const allMembers = _.unionBy(contacts, members, 'patp'); const pending: Participant[] = @@ -303,11 +307,13 @@ function Participant(props: { return ( <> {avatar} - + {hasNickname && ( - + + {contact.nickname} + )} {cite(contact.patp)}