import { Firestore } from '../../../firebase/Firestore' ; import { ISODateTimeString } from 'polar-shared/src/metadata/ISODateTimeStrings' ; import { GroupIDStr } from '../../Datastore' ; import { Hashcodes } from 'polar-shared/src/util/Hashcodes' ; import { ExternalLink } from "../rpc/GroupProvisions" ; import { Clause , Collections , OrderByClause } from "./Collections" ; import { PlainTextStr , URLStr } from "polar-shared/src/util/Strings" ; import { Arrays } from "polar-shared/src/util/Arrays" ; import { UserIDStr } from "polar-firebase/src/firebase/om/Profiles" ; const HASHCODE_LEN = 20 ; export class Groups { public static readonly COLLECTION = 'group' ; public static createIDForKey ( uid , key ) { return Hashcodes . createID ( { key , uid } , HASHCODE_LEN ) ; } public static async get ( id ) { const firestore = await Firestore . getInstance ( ) ; const ref = firestore . collection ( this . COLLECTION ) . doc ( id ) ; const doc = await ref . get ( ) ; return < Group > doc . data ( ) ; } public static async getAll ( identifiers ) { const promises = identifiers . map ( id => this . get ( id ) ) ; const resolved = await Promise . all ( promises ) ; return Arrays . onlyDefined ( resolved ) ; } public static async getByName ( name ) { const clauses = [ [ 'visibility' , '==' , 'public' ] , [ 'name' , '==' , name ] ] ; return Collections . getByFieldValues ( this . COLLECTION , clauses ) ; } public static async executeSearchWithTags ( tags ) { const visibilityClauses = [ [ 'visibility' , '==' , 'public' ] ] ; const tagClauses = tags . map ( current => [ 'tags' , 'array-contains' , current ] ) ; const clauses = [ ... visibilityClauses , ... tagClauses ] ; const orderBy = [ [ 'nrMembers' , 'desc' ] ] ; const limit = 50 ; return await Collections . list ( this . COLLECTION , clauses , { orderBy , limit } ) ; } public static async topGroups ( ) { const visibilityClauses = [ [ 'visibility' , '==' , 'public' ] ] ; const clauses = [ ... visibilityClauses ] ; const orderBy = [ [ 'nrMembers' , 'desc' ] , [ 'name' , 'asc' ] ] ; const limit = 50 ; return await Collections . list ( this . COLLECTION , clauses , { orderBy , limit } ) ; } } export interface GroupInit { /**
     * When specified, use the given group name.
     */ readonly name ? : string ; /**
     * Must set the group visibility here so that we inherit the right value.
     */ readonly visibility : GroupVisibility ; readonly tags ? : ReadonlyArray < TagStr > ; /**
     * A string (not HTML) that is used as a description for this document.
     */ readonly description ? : PlainTextStr ; readonly links ? : ReadonlyArray < URLStr | ExternalLink > ; } export interface Group extends GroupInit { readonly id : GroupIDStr ; readonly nrMembers : number ; readonly created : ISODateTimeString ; } export type GroupVisibility = 'private' | 'protected' | 'public' ; export type TagStr = string ; export type GroupNameStr = string ;