import { observable, runInAction, action, autorun } from "mobx"; import * as React from "react"; import MainViewModal from "../views/MainViewModal"; import { CurrentUserUtils } from "../../server/authentication/models/current_user_utils"; import { Doc, Opt } from "../../new_fields/Doc"; import { DocServer } from "../DocServer"; import { Cast, StrCast } from "../../new_fields/Types"; import { listSpec } from "../../new_fields/Schema"; import { List } from "../../new_fields/List"; import { RouteStore } from "../../server/RouteStore"; import * as RequestPromise from "request-promise"; import { Utils } from "../../Utils"; import "./SharingManager.scss"; import { Id } from "../../new_fields/FieldSymbols"; import { observer } from "mobx-react"; import { MainView } from "../views/MainView"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { library } from '@fortawesome/fontawesome-svg-core'; import * as fa from '@fortawesome/free-solid-svg-icons'; import { DocumentView } from "../views/nodes/DocumentView"; import { SelectionManager } from "./SelectionManager"; import { DocumentManager } from "./DocumentManager"; import { CollectionVideoView } from "../views/collections/CollectionVideoView"; import { CollectionPDFView } from "../views/collections/CollectionPDFView"; import { CollectionView } from "../views/collections/CollectionView"; library.add(fa.faCopy); export interface User { email: string; userDocumentId: string; } export enum SharingPermissions { None = "Not Shared", View = "Can View", Comment = "Can Comment", Edit = "Can Edit" } const ColorMapping = new Map([ [SharingPermissions.None, "red"], [SharingPermissions.View, "maroon"], [SharingPermissions.Comment, "blue"], [SharingPermissions.Edit, "green"] ]); const SharingKey = "sharingPermissions"; const PublicKey = "publicLinkPermissions"; const DefaultColor = "black"; @observer export default class SharingManager extends React.Component<{}> { public static Instance: SharingManager; @observable private isOpen = false; @observable private users: User[] = []; @observable private targetDoc: Doc | undefined; @observable private targetDocView: DocumentView | undefined; @observable private copied = false; @observable private dialogueBoxOpacity = 1; @observable private overlayOpacity = 0.4; private get linkVisible() { return this.sharingDoc ? this.sharingDoc[PublicKey] !== SharingPermissions.None : false; } public open = (target: DocumentView) => { SelectionManager.DeselectAll(); this.populateUsers().then(action(() => { this.targetDocView = target; this.targetDoc = target.props.Document; MainView.Instance.hasActiveModal = true; this.isOpen = true; if (!this.sharingDoc) { this.sharingDoc = new Doc; } })); } public close = action(() => { this.isOpen = false; setTimeout(action(() => { this.copied = false; MainView.Instance.hasActiveModal = false; this.targetDoc = undefined; }), 500); }); private get sharingDoc() { return this.targetDoc ? Cast(this.targetDoc[SharingKey], Doc) as Doc : undefined; } private set sharingDoc(value: Doc | undefined) { this.targetDoc && (this.targetDoc[SharingKey] = value); } constructor(props: {}) { super(props); SharingManager.Instance = this; } populateUsers = async () => { let userList = await RequestPromise.get(Utils.prepend(RouteStore.getUsers)); runInAction(() => { this.users = (JSON.parse(userList) as User[]).filter(({ email }) => email !== CurrentUserUtils.email); }); } setInternalSharing = async (user: User, state: string) => { if (!this.sharingDoc) { console.log("SHARING ABORTED!"); return; } let sharingDoc = await this.sharingDoc; sharingDoc[user.userDocumentId] = state; const userDocument = await DocServer.GetRefField(user.userDocumentId); if (!(userDocument instanceof Doc)) { console.log(`Couldn't get user document of user ${user.email}`); return; } let target = this.targetDoc; if (!target) { console.log("SharingManager trying to share an undefined document!!"); return; } const notifDoc = await Cast(userDocument.optionalRightCollection, Doc); if (notifDoc instanceof Doc) { const data = await Cast(notifDoc.data, listSpec(Doc)); if (!data) { console.log("UNABLE TO ACCESS NOTIFICATION DATA"); return; } console.log(`Attempting to set permissions to ${state} for the document ${target[Id]}`); if (state !== SharingPermissions.None) { const sharedDoc = Doc.MakeAlias(target); if (data) { data.push(sharedDoc); } else { notifDoc.data = new List([sharedDoc]); } } else { let dataDocs = (await Promise.all(data.map(doc => doc))).map(doc => Doc.GetProto(doc)); if (dataDocs.includes(target)) { console.log("Searching in ", dataDocs, "for", target); dataDocs.splice(dataDocs.indexOf(target), 1); console.log("SUCCESSFULLY UNSHARED DOC"); } else { console.log("DIDN'T THINK WE HAD IT, SO NOT SUCCESSFULLY UNSHARED"); } } } } private setExternalSharing = (state: string) => { let sharingDoc = this.sharingDoc; if (!sharingDoc) { return; } sharingDoc[PublicKey] = state; } private get sharingUrl() { if (!this.targetDoc) { return undefined; } let baseUrl = Utils.prepend("/doc/" + this.targetDoc[Id]); return `${baseUrl}?sharing=true`; } copy = action(() => { if (this.sharingUrl) { Utils.CopyText(this.sharingUrl); this.copied = true; } }); private get sharingOptions() { return Object.values(SharingPermissions).map(permission => { return ( ); }); } private focusOn = (contents: string) => { let title = this.targetDoc ? StrCast(this.targetDoc.title) : ""; return ( { let context: Opt; if (this.targetDoc && this.targetDocView && (context = this.targetDocView.props.ContainingCollectionView)) { DocumentManager.Instance.jumpToDocument(this.targetDoc, true, undefined, undefined, undefined, context.props.Document); } }} onPointerEnter={action(() => { if (this.targetDoc) { Doc.BrushDoc(this.targetDoc); this.dialogueBoxOpacity = 0.1; this.overlayOpacity = 0.1; } })} onPointerLeave={action(() => { this.targetDoc && Doc.UnBrushDoc(this.targetDoc); this.dialogueBoxOpacity = 1; this.overlayOpacity = 0.4; })} > {contents} ); } private get sharingInterface() { return (

Manage the public link to {this.focusOn("this document...")}

{!this.linkVisible ? (null) :
{this.sharingUrl}
}
{!this.linkVisible ? (null) :

People with this link

}

Privately share {this.focusOn("this document")} with an individual...

{!this.users.length ? "There are no other users in your database." : this.users.map(user => { return (
{user.email}
); }) }
Done
); } render() { return ( ); } }