Skip to content

Commit

Permalink
Adding embed editing in issues and patches
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastinez committed Nov 21, 2023
1 parent eeba820 commit f196e18
Show file tree
Hide file tree
Showing 16 changed files with 85 additions and 63 deletions.
3 changes: 2 additions & 1 deletion httpd-client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type {
Tree,
DiffResponse,
} from "./lib/project.js";
import type { Comment } from "./lib/project/comment.js";
import type { Comment, Embed } from "./lib/project/comment.js";
import type {
Commit,
CommitBlob,
Expand Down Expand Up @@ -52,6 +52,7 @@ export type {
DiffContent,
DiffFile,
DiffResponse,
Embed,
HunkLine,
Issue,
IssueState,
Expand Down
2 changes: 1 addition & 1 deletion httpd-client/lib/project.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Embed } from "@app/lib/file.js";
import type { Commit, Commits } from "./project/commit.js";
import type { Embed } from "./project/comment.js";
import type { Fetcher, RequestOptions } from "./fetcher.js";
import type {
Issue,
Expand Down
3 changes: 1 addition & 2 deletions httpd-client/lib/project/issue.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { Embed } from "@app/lib/file.js";
import type { Comment } from "./comment.js";
import type { Comment, Embed } from "./comment.js";
import type { ZodSchema } from "zod";
import { array, boolean, literal, object, string, union } from "zod";

Expand Down
3 changes: 1 addition & 2 deletions httpd-client/lib/project/patch.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { Embed } from "@app/lib/file.js";
import type { Comment } from "./comment.js";
import type { Comment, Embed } from "./comment.js";
import type { ZodSchema, z } from "zod";

import { commentSchema } from "./comment.js";
Expand Down
6 changes: 4 additions & 2 deletions src/components/Comment.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts" strictEvents>
import type { Embed } from "@app/lib/file";
import type { Embed } from "@httpd-client";
import type { GroupedReactions } from "@app/lib/reactions";
import { tick } from "svelte";
Expand All @@ -21,6 +21,7 @@
export let body: string;
export let enableAttachments: boolean = false;
export let reactions: GroupedReactions | undefined = undefined;
export let embeds: Map<string, Embed> | undefined = undefined;
export let caption = "commented";
export let rawPath: string;
export let timestamp: number;
Expand Down Expand Up @@ -144,14 +145,15 @@
{@const editComment_ = editComment}
<ExtendedTextarea
{body}
{embeds}
{enableAttachments}
submitInProgress={state === "submit"}
submitCaption="Save"
placeholder="Leave your comment"
on:submit={async ({ detail: { comment, embeds } }) => {
state = "submit";
try {
await editComment_(comment, embeds);
await editComment_(comment, Array.from(embeds.values()));
} finally {
state = "read";
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/CommentToggleInput.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import type { Embed } from "@app/lib/file";
import type { Embed } from "@httpd-client";
import ExtendedTextarea from "@app/components/ExtendedTextarea.svelte";
Expand Down Expand Up @@ -42,7 +42,7 @@
on:submit={async ({ detail: { comment, embeds } }) => {
try {
state = "submit";
await submit(comment, embeds);
await submit(comment, Array.from(embeds.values()));
} finally {
state = "collapsed";
}
Expand Down
30 changes: 11 additions & 19 deletions src/components/ExtendedTextarea.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts" strictEvents>
import type { Embed, EmbedWithOid } from "@app/lib/file";
import type { Embed } from "@httpd-client";
import { createEventDispatcher } from "svelte";
Expand All @@ -22,26 +22,25 @@
export let focus: boolean = false;
export let inline: boolean = false;
export let body: string = "";
export let embeds: Map<string, Embed> = new Map();
export let submitInProgress: boolean = false;
let preview: boolean = false;
let newEmbeds: EmbedWithOid[] = [];
let selectionStart = 0;
let selectionEnd = 0;
let inputFiles: FileList | undefined = undefined;
const inputId = `input-label-${crypto.randomUUID()}`;
const dispatch = createEventDispatcher<{
submit: { comment: string; embeds: Embed[] };
submit: { comment: string; embeds: Map<string, Embed> };
close: null;
click: null;
}>();
function submit() {
dispatch("submit", { comment: body, embeds: newEmbeds });
dispatch("submit", { comment: body, embeds });
preview = false;
newEmbeds = [];
}
const MAX_BLOB_SIZE = 4_194_304;
Expand Down Expand Up @@ -85,10 +84,10 @@
}
function attachEmbeds(files: FileList) {
const embeds = Array.from(files).map(embed);
void Promise.all(embeds).then(embeds =>
embeds.forEach(embed => {
if (embed.content.length > MAX_BLOB_SIZE) {
const embedPromise = Array.from(files).map(embed);
void Promise.all(embedPromise).then(newEmbeds =>
newEmbeds.forEach(({ oid, name, content }) => {
if (content.length > MAX_BLOB_SIZE) {
modal.show({
component: ErrorModal,
props: {
Expand All @@ -102,15 +101,8 @@
});
return;
}
newEmbeds = [
...newEmbeds,
{
oid: embed.oid,
name: embed.name,
content: embed.content,
},
];
const embedText = `![${embed.name}](${embed.oid})\n`;
embeds.set(oid, { name, content });
const embedText = `![${name}](${oid})\n`;
body = body
.slice(0, selectionStart)
.concat(embedText, body.slice(selectionEnd));
Expand Down Expand Up @@ -195,7 +187,7 @@
</Radio>
{#if preview}
<div class="preview">
<Markdown content={body} embeds={newEmbeds} />
<Markdown content={body} {embeds} />
</div>
{:else}
<input
Expand Down
13 changes: 4 additions & 9 deletions src/components/Markdown.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import type { EmbedWithOid } from "@app/lib/file";
import type { Embed } from "@httpd-client";
import dompurify from "dompurify";
import matter from "@radicle/gray-matter";
Expand All @@ -26,7 +26,7 @@
export let rawPath: string | undefined = undefined;
// If present, means we are in a preview context,
// use this for image previews instead of /raw URLs.
export let embeds: EmbedWithOid[] | undefined = undefined;
export let embeds: Map<string, Embed> | undefined = undefined;
$: doc = matter(content);
$: frontMatter = Object.entries(doc.data).filter(
Expand Down Expand Up @@ -85,14 +85,9 @@
// If the image is an oid embed
if (imagePath && isCommit(imagePath)) {
const embed = embeds?.find(e => {
return e.oid === imagePath;
});
const embed = embeds?.get(imagePath);
if (embed) {
const fileExtension = embed.name.split(".").pop();
if (fileExtension) {
i.setAttribute("src", embed.content);
}
i.setAttribute("src", embed.content);
}
}
}
Expand Down
9 changes: 6 additions & 3 deletions src/components/Thread.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@
</script>

<script lang="ts" strictEvents>
import type { Embed } from "@app/lib/file";
import type { Embed } from "@httpd-client";
import * as utils from "@app/lib/utils";
import { parseEmbedIntoMap } from "@app/lib/file";
import { partial } from "lodash";
import { tick } from "svelte";
Expand Down Expand Up @@ -89,13 +90,14 @@
? "1px solid var(--color-fill-separator)"
: undefined}>
<CommentComponent
{enableAttachments}
{rawPath}
id={root.id}
authorId={root.author.id}
authorAlias={root.author.alias}
reactions={root.reactions}
embeds={parseEmbedIntoMap(root.embeds)}
timestamp={root.timestamp}
disableEdit={root.embeds.length > 0}
body={root.body}
editComment={editComment &&
canEditComment(root.author.id) &&
Expand All @@ -108,6 +110,7 @@
<div class="replies">
{#each replies as reply}
<CommentComponent
{enableAttachments}
{rawPath}
id={reply.id}
authorId={reply.author.id}
Expand All @@ -116,8 +119,8 @@
isReply
isLastReply={replies[replies.length - 1] === reply}
reactions={reply.reactions}
embeds={parseEmbedIntoMap(reply.embeds)}
timestamp={reply.timestamp}
disableEdit={reply.embeds.length > 0}
body={reply.body}
editComment={editComment &&
canEditComment(reply.author.id) &&
Expand Down
17 changes: 9 additions & 8 deletions src/lib/file.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
export interface Embed {
name: string;
content: string;
}
export interface EmbedWithOid extends Embed {
oid: string;
}
import type { Embed } from "@httpd-client";

async function parseGitOid(bytes: Uint8Array): Promise<string> {
// Create the header
Expand Down Expand Up @@ -38,6 +32,13 @@ function base64String(file: File): Promise<string> {
});
}

export function parseEmbedIntoMap(embeds: Embed[]) {
return embeds.reduce((acc, embed) => {
acc.set(embed.content.substring(4), embed);
return acc;
}, new Map());
}

const mimes: Record<string, string> = {
"3gp": "video/3gpp",
"7z": "application/x-7z-compressed",
Expand Down Expand Up @@ -101,7 +102,7 @@ const mimes: Record<string, string> = {
zip: "application/zip",
};

async function embed(file: File): Promise<EmbedWithOid> {
async function embed(file: File) {
const bytes = new Uint8Array(await file.arrayBuffer());
const oid = await parseGitOid(bytes);
const content = await base64String(file);
Expand Down
2 changes: 1 addition & 1 deletion src/views/projects/Cob/Embeds.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts" strictEvents>
import type { Embed } from "@app/lib/file";
import type { Embed } from "@httpd-client";
import Badge from "@app/components/Badge.svelte";
import Clipboard from "@app/components/Clipboard.svelte";
Expand Down
2 changes: 1 addition & 1 deletion src/views/projects/Cob/Revision.svelte
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<script lang="ts">
import type { Embed } from "@httpd-client/lib/project/comment";
import type {
BaseUrl,
DiffResponse,
Embed,
PatchState,
Verdict,
} from "@httpd-client";
Expand Down
18 changes: 15 additions & 3 deletions src/views/projects/Issue.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
<script lang="ts">
import type { BaseUrl, Issue, IssueState, Project } from "@httpd-client";
import type { Embed } from "@app/lib/file";
import type {
BaseUrl,
Issue,
IssueState,
Embed,
Project,
} from "@httpd-client";
import type { Session } from "@app/lib/httpd";
import { isEqual, uniqBy, partial } from "lodash";
Expand All @@ -13,6 +18,7 @@
import { closeFocused } from "@app/components/Popover.svelte";
import { groupReactions } from "@app/lib/reactions";
import { httpdStore } from "@app/lib/httpd";
import { parseEmbedIntoMap } from "@app/lib/file";
import AssigneeInput from "@app/views/projects/Cob/AssigneeInput.svelte";
import Badge from "@app/components/Badge.svelte";
Expand Down Expand Up @@ -475,6 +481,7 @@
{#if descriptionState !== "read"}
<ExtendedTextarea
enableAttachments
embeds={parseEmbedIntoMap(issue.discussion[0].embeds)}
body={issue.discussion[0].body}
submitCaption="Save"
submitInProgress={descriptionState === "submit"}
Expand All @@ -484,7 +491,12 @@
if (session) {
try {
descriptionState = "submit";
await editComment(session.id, issue.id, comment, embeds);
await editComment(
session.id,
issue.id,
comment,
Array.from(embeds.values()),
);
} finally {
descriptionState = "read";
}
Expand Down
10 changes: 3 additions & 7 deletions src/views/projects/Issue/New.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<script lang="ts">
import type { BaseUrl, Project } from "@httpd-client";
import type { EmbedWithOid } from "@app/lib/file";
import type { BaseUrl, Embed, Project } from "@httpd-client";
import * as modal from "@app/lib/modal";
import * as router from "@app/lib/router";
Expand All @@ -26,7 +25,6 @@
export let project: Project;
export let tracking: boolean;
let newEmbeds: EmbedWithOid[] = [];
let preview: boolean = false;
let selectionStart = 0;
let selectionEnd = 0;
Expand All @@ -39,17 +37,15 @@
let creatingIssue: boolean = false;
const api = new HttpdClient(baseUrl);
const newEmbeds = new Map<string, Embed>();
function handleFileDrop(event: { detail: DragEvent }) {
event.detail.preventDefault();
if (event.detail.dataTransfer) {
const embeds = Array.from(event.detail.dataTransfer.files).map(embed);
void Promise.all(embeds).then(embeds =>
embeds.forEach(({ oid, name, content }) => {
newEmbeds = [
...newEmbeds,
{ oid: oid, name: name, content: content },
];
newEmbeds.set(oid, { name, content });
const embedText = `![${name}](${oid})\n`;
issueText = issueText
.slice(0, selectionStart)
Expand Down
3 changes: 1 addition & 2 deletions src/views/projects/Patch.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@
</script>

<script lang="ts">
import type { BaseUrl, Patch } from "@httpd-client";
import type { Embed } from "@app/lib/file";
import type { BaseUrl, Embed, Patch } from "@httpd-client";
import type { PatchView } from "./router";
import type { Route } from "@app/lib/router";
import type { ComponentProps } from "svelte";
Expand Down
Loading

0 comments on commit f196e18

Please sign in to comment.