<commit_before>package peergos.shared.social;

import jsinterop.annotations.*;
import peergos.shared.cbor.*;
import peergos.shared.crypto.hash.*;
import peergos.shared.io.ipfs.multihash.*;
import peergos.shared.user.fs.*;

import java.time.*;
import java.util.*;
import java.util.concurrent.*;

@JsType
public class SocialPost implements Cborable {
    public enum Type {
        Text, // body is just text
        Image, // 1 image in references
        Video, // 1 video in references
        Audio, // 1 audio file in references
        Media, // several images/video/audio files in references
        Poll // votes are merged in as comments, options are in body
    }

    public final Type kind;
    public final String author;
    public final String body;
    public final List<String> tags;
    public final LocalDateTime postTime;
    public final boolean resharingAllowed;
    public final boolean isPublic;
    public final Optional<Ref> parent;
    public final List<MutableRef> references;
    public final List<SocialPost> previousVersions;
    // this is excluded from hash calculation when replying
    public final List<Ref> comments;

    @JsConstructor
    public SocialPost(Type kind,
                      String author,
                      String body,
                      List<String> tags,
                      LocalDateTime postTime,
                      boolean resharingAllowed,
                      boolean isPublic,
                      Optional<Ref> parent,
                      List<MutableRef> references,
                      List<SocialPost> previousVersions,
                      List<Ref> comments) {
        this.kind = kind;
        this.author = author;
        this.body = body;
        this.tags = tags;
        this.postTime = postTime;
        this.resharingAllowed = resharingAllowed;
        this.isPublic = isPublic;
        this.parent = parent;
        this.references = references;
        this.previousVersions = previousVersions;
        this.comments = comments;
    }

    public static SocialPost createInitialPost(Type type, String author, String body, List<String> tags) {
        return new SocialPost(type, author, body, tags, LocalDateTime.now(), true, false,
                Optional.empty(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
    }

    public SocialPost edit(String body,
                           List<String> tags,
                           LocalDateTime postTime,
                           List<MutableRef> references) {
        ArrayList<SocialPost> versions = new ArrayList<>(previousVersions);
        versions.add(this);
        return new SocialPost(kind, author, body, tags, postTime, resharingAllowed, isPublic, parent, references, versions, comments);
    }

    /** adding references to comments does not change the version of this comment (the hash ignores the comment refs)
     *
     * @param comment
     * @return
     */
    public SocialPost addComment(Ref comment) {
        ArrayList<Ref> updatedComments = new ArrayList<>(comments);
        if (! comments.contains(comment))
            updatedComments.add(comment);
        return new SocialPost(kind, author, body, tags, postTime, resharingAllowed, isPublic, parent, references,
                previousVersions, updatedComments);
    }

    private byte[] serializeWithoutComments() {
        return new SocialPost(kind, author, body, tags, postTime, resharingAllowed, isPublic, parent, references,
                previousVersions, Collections.emptyList()).serialize();
    }

    public CompletableFuture<Multihash> contentHash(Hasher h) {<commit_msg>Add convenience method for creating a comment on a social post<commit_after>package peergos.shared.social;

import jsinterop.annotations.*;
import peergos.shared.cbor.*;
import peergos.shared.crypto.hash.*;
import peergos.shared.io.ipfs.multihash.*;
import peergos.shared.user.fs.*;

import java.time.*;
import java.util.*;
import java.util.concurrent.*;

@JsType
public class SocialPost implements Cborable {
    public enum Type {
        Text, // body is just text
        Image, // 1 image in references
        Video, // 1 video in references
        Audio, // 1 audio file in references
        Media, // several images/video/audio files in references
        Poll // votes are merged in as comments, options are in body
    }

    public final Type kind;
    public final String author;
    public final String body;
    public final List<String> tags;
    public final LocalDateTime postTime;
    public final boolean resharingAllowed;
    public final boolean isPublic;
    public final Optional<Ref> parent;
    public final List<MutableRef> references;
    public final List<SocialPost> previousVersions;
    // this is excluded from hash calculation when replying
    public final List<Ref> comments;

    @JsConstructor
    public SocialPost(Type kind,
                      String author,
                      String body,
                      List<String> tags,
                      LocalDateTime postTime,
                      boolean resharingAllowed,
                      boolean isPublic,
                      Optional<Ref> parent,
                      List<MutableRef> references,
                      List<SocialPost> previousVersions,
                      List<Ref> comments) {
        this.kind = kind;
        this.author = author;
        this.body = body;
        this.tags = tags;
        this.postTime = postTime;
        this.resharingAllowed = resharingAllowed;
        this.isPublic = isPublic;
        this.parent = parent;
        this.references = references;
        this.previousVersions = previousVersions;
        this.comments = comments;
    }

    public static SocialPost createInitialPost(Type type, String author, String body, List<String> tags) {
        return new SocialPost(type, author, body, tags, LocalDateTime.now(), true, false,
                Optional.empty(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
    }

    public static SocialPost createComment(Ref parent, Type type, String author, String body, List<String> tags) {
        return new SocialPost(type, author, body, tags, LocalDateTime.now(), true, false,
                Optional.of(parent), Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
    }

    public SocialPost edit(String body,
                           List<String> tags,
                           LocalDateTime postTime,
                           List<MutableRef> references) {
        ArrayList<SocialPost> versions = new ArrayList<>(previousVersions);
        versions.add(this);
        return new SocialPost(kind, author, body, tags, postTime, resharingAllowed, isPublic, parent, references, versions, comments);
    }

    /** adding references to comments does not change the version of this comment (the hash ignores the comment refs)
     *
     * @param comment
     * @return
     */
    public SocialPost addComment(Ref comment) {
        ArrayList<Ref> updatedComments = new ArrayList<>(comments);
        if (! comments.contains(comment))
            updatedComments.add(comment);
        return new SocialPost(kind, author, body, tags, postTime, resharingAllowed, isPublic, parent, references,
                previousVersions, updatedComments);
    }

    private byte[] serializeWithoutComments() {
        return new SocialPost(kind, author, body, tags, postTime, resharingAllowed, isPublic, parent, references,
                previousVersions, Collections.emptyList()).serialize();
    }

    public CompletableFuture<Multihash> contentHash(Hasher h) {
{'fraction_non_alphanumeric': 0.0837245696400626, 'fraction_numerical': 0.000782472613458529, 'mean_word_length': 2.416035634743875, 'pattern_counts': {'":': 0, '<': 40, '<?xml version=': 0, '>': 40, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5897972', 'n_tokens_mistral': 1911, 'n_tokens_neox': 1848, 'n_words': 596}