chat-pane
Version:
Solid-compatible Panes: Chat
149 lines (147 loc) • 5.12 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.findChat = findChat;
exports.getChat = getChat;
var _solidUi = require("solid-ui");
var _solidLogic = require("solid-logic");
var _rdflib = require("rdflib");
var _longChatPane = require("./longChatPane");
async function getMe() {
const me = _solidLogic.authn.currentUser();
if (me === null) {
throw new Error('Current user not found! Not logged in?');
}
await _solidLogic.store.fetcher.load(me.doc());
return me;
}
async function getPodRoot(me) {
const podRoot = _solidLogic.store.any(me, _solidUi.ns.space('storage'), undefined, me.doc());
if (!podRoot) {
throw new Error('Current user pod root not found!');
}
return podRoot;
}
async function sendInvite(invitee, chatThing) {
await _solidLogic.store.fetcher.load(invitee.doc());
const inviteeInbox = _solidLogic.store.any(invitee, _solidUi.ns.ldp('inbox'), undefined, invitee.doc());
if (!inviteeInbox) {
throw new Error(`Invitee inbox not found! ${invitee.value}`);
}
const inviteBody = `
<> a <http://www.w3.org/ns/pim/meeting#LongChatInvite> ;
${_solidUi.ns.rdf('seeAlso')} <${chatThing.value}> .
`;
const inviteResponse = await _solidLogic.store.fetcher.webOperation('POST', inviteeInbox.value, {
data: inviteBody,
contentType: 'text/turtle'
});
const locationStr = inviteResponse.headers.get('location');
if (!locationStr) {
throw new Error(`Invite sending returned a ${inviteResponse.status}`);
}
}
function determineChatContainer(invitee, podRoot) {
// Create chat
// See https://gitter.im/solid/chat-app?at=5f3c800f855be416a23ae74a
const chatContainerStr = new URL(`IndividualChats/${new URL(invitee.value).host}/`, podRoot.value).toString();
return new _rdflib.NamedNode(chatContainerStr);
}
async function createChatThing(chatContainer, me) {
const created = await _longChatPane.longChatPane.mintNew({
session: {
store: _solidLogic.store
}
}, {
me,
newBase: chatContainer.value
});
return created.newInstance;
}
async function setAcl(chatContainer, me, invitee) {
// Some servers don't present a Link http response header
// if the container doesn't exist yet, so refetch the container
// now that it has been created:
await _solidLogic.store.fetcher.load(chatContainer);
// FIXME: check the Why value on this quad:
const chatAclDoc = _solidLogic.store.any(chatContainer, new _rdflib.NamedNode('http://www.iana.org/assignments/link-relations/acl'));
if (!chatAclDoc) {
throw new Error('Chat ACL doc not found!');
}
const aclBody = `
@prefix acl: <http://www.w3.org/ns/auth/acl#>.
<#owner>
a acl:Authorization;
acl:agent <${me.value}>;
acl:accessTo <.>;
acl:default <.>;
acl:mode
acl:Read, acl:Write, acl:Control.
<#invitee>
a acl:Authorization;
acl:agent <${invitee.value}>;
acl:accessTo <.>;
acl:default <.>;
acl:mode
acl:Read, acl:Append.
`;
const aclResponse = await _solidLogic.store.fetcher.webOperation('PUT', chatAclDoc.value, {
data: aclBody,
contentType: 'text/turtle'
});
}
async function addToPrivateTypeIndex(chatThing, me) {
// Add to private type index
const privateTypeIndex = _solidLogic.store.any(me, _solidUi.ns.solid('privateTypeIndex'));
if (!privateTypeIndex) {
throw new Error('Private type index not found!');
}
await _solidLogic.store.fetcher.load(privateTypeIndex);
const reg = _solidUi.widgets.newThing(privateTypeIndex);
const ins = [(0, _rdflib.st)(reg, _solidUi.ns.rdf('type'), _solidUi.ns.solid('TypeRegistration'), privateTypeIndex.doc()), (0, _rdflib.st)(reg, _solidUi.ns.solid('forClass'), _solidUi.ns.meeting('LongChat'), privateTypeIndex.doc()), (0, _rdflib.st)(reg, _solidUi.ns.solid('instance'), chatThing, privateTypeIndex.doc())];
await new Promise((resolve, reject) => {
_solidLogic.store.updater.update([], ins, function (_uri, ok, errm) {
if (!ok) {
reject(new Error(errm));
} else {
resolve();
}
});
});
}
async function findChat(invitee) {
const me = await getMe();
const podRoot = await getPodRoot(me);
const chatContainer = determineChatContainer(invitee, podRoot);
let exists = true;
try {
await _solidLogic.store.fetcher.load(new _rdflib.NamedNode(chatContainer.value + _longChatPane.longChatPane.CHAT_LOCATION_IN_CONTAINER));
} catch (e) {
exists = false;
}
return {
me,
chatContainer,
exists
};
}
async function getChat(invitee, createIfMissing = true) {
const {
me,
chatContainer,
exists
} = await findChat(invitee);
if (exists) {
return new _rdflib.NamedNode(chatContainer.value + _longChatPane.longChatPane.CHAT_LOCATION_IN_CONTAINER);
}
if (createIfMissing) {
const chatThing = await createChatThing(chatContainer, me);
await sendInvite(invitee, chatThing);
await setAcl(chatContainer, me, invitee);
await addToPrivateTypeIndex(chatThing, me);
return chatThing;
}
throw new Error('Chat does not exist and createIfMissing is false');
}
//# sourceMappingURL=create.js.map