Spaces:
Runtime error
Runtime error
push state to Spaces
Browse files- frontend/src/lib/App.svelte +2 -7
- frontend/src/lib/Buttons/AboutButton.svelte +3 -3
- frontend/src/lib/Buttons/RoomsSelector.svelte +1 -0
- frontend/src/lib/Buttons/ShareWithCommunity.svelte +12 -4
- frontend/src/lib/Menu.svelte +12 -7
- frontend/src/lib/PaintFrame.svelte +5 -4
- frontend/src/lib/types.ts +1 -1
- frontend/src/lib/utils.ts +0 -5
- frontend/src/routes/+page.svelte +6 -2
frontend/src/lib/App.svelte
CHANGED
@@ -3,12 +3,11 @@
|
|
3 |
import Frame from '$lib/Frame.svelte';
|
4 |
import PaintFrame from '$lib/PaintFrame.svelte';
|
5 |
import PaintCanvas from '$lib/PaintCanvas.svelte';
|
6 |
-
import ShareWithCommunity from '$lib/Buttons/ShareWithCommunity.svelte';
|
7 |
import Menu from '$lib/Menu.svelte';
|
8 |
import PromptModal from '$lib/PromptModal.svelte';
|
9 |
import { COLORS } from '$lib/constants';
|
10 |
import { PUBLIC_WS_INPAINTING } from '$env/static/public';
|
11 |
-
import type { PromptImgKey } from '$lib/types';
|
12 |
import { Status } from '$lib/types';
|
13 |
import {
|
14 |
loadingState,
|
@@ -18,7 +17,6 @@
|
|
18 |
isRenderingCanvas
|
19 |
} from '$lib/store';
|
20 |
import { useMyPresence, useObject, useOthers } from '$lib/liveblocks';
|
21 |
-
import { base64ToBlob, uploadImage } from '$lib/utils';
|
22 |
import { nanoid } from 'nanoid';
|
23 |
|
24 |
const myPresence = useMyPresence({ addToHistory: true });
|
@@ -70,7 +68,7 @@
|
|
70 |
};
|
71 |
|
72 |
const datapayload = {
|
73 |
-
data: [base64Crop, prompt, 0.75, 7.5, 40, 'patchmatch']
|
74 |
};
|
75 |
|
76 |
const websocket = new WebSocket(PUBLIC_WS_INPAINTING);
|
@@ -205,9 +203,6 @@
|
|
205 |
{/if}
|
206 |
</main>
|
207 |
</div>
|
208 |
-
<!-- <div class="fixed top-0 right-0 z-10 p-2">
|
209 |
-
<ShareWithCommunity />
|
210 |
-
</div> -->
|
211 |
<div class="fixed bottom-2 md:bottom-16 left-0 right-0 z-10 my-2">
|
212 |
<Menu on:prompt={onPrompt} {isLoading} />
|
213 |
</div>
|
|
|
3 |
import Frame from '$lib/Frame.svelte';
|
4 |
import PaintFrame from '$lib/PaintFrame.svelte';
|
5 |
import PaintCanvas from '$lib/PaintCanvas.svelte';
|
|
|
6 |
import Menu from '$lib/Menu.svelte';
|
7 |
import PromptModal from '$lib/PromptModal.svelte';
|
8 |
import { COLORS } from '$lib/constants';
|
9 |
import { PUBLIC_WS_INPAINTING } from '$env/static/public';
|
10 |
+
import type { PromptImgKey, PromptImgObject } from '$lib/types';
|
11 |
import { Status } from '$lib/types';
|
12 |
import {
|
13 |
loadingState,
|
|
|
17 |
isRenderingCanvas
|
18 |
} from '$lib/store';
|
19 |
import { useMyPresence, useObject, useOthers } from '$lib/liveblocks';
|
|
|
20 |
import { nanoid } from 'nanoid';
|
21 |
|
22 |
const myPresence = useMyPresence({ addToHistory: true });
|
|
|
68 |
};
|
69 |
|
70 |
const datapayload = {
|
71 |
+
data: [base64Crop, prompt, 0.75, 7.5, 40, 'patchmatch', room]
|
72 |
};
|
73 |
|
74 |
const websocket = new WebSocket(PUBLIC_WS_INPAINTING);
|
|
|
203 |
{/if}
|
204 |
</main>
|
205 |
</div>
|
|
|
|
|
|
|
206 |
<div class="fixed bottom-2 md:bottom-16 left-0 right-0 z-10 my-2">
|
207 |
<Menu on:prompt={onPrompt} {isLoading} />
|
208 |
</div>
|
frontend/src/lib/Buttons/AboutButton.svelte
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
-
<div class="md:w-[210px] text-sm md:flex flex-col order-last md:order-none">
|
2 |
-
<p class="
|
3 |
Instructions: move the <span class="text-blue-700 bg-blue-300/60 px-0.5">blue square</span>,
|
4 |
-
click "π Paint"
|
5 |
</p>
|
6 |
<button on:click class="items-center inline-flex">
|
7 |
<svg width=".9em" height=".9em" viewBox="0 0 24 24" class="mr-1"
|
|
|
1 |
+
<div class="md:w-[210px] text-sm md:flex flex-col order-last md:order-none py-4">
|
2 |
+
<p class="inline pb-3">
|
3 |
Instructions: move the <span class="text-blue-700 bg-blue-300/60 px-0.5">blue square</span>,
|
4 |
+
click "π Paint".
|
5 |
</p>
|
6 |
<button on:click class="items-center inline-flex">
|
7 |
<svg width=".9em" height=".9em" viewBox="0 0 24 24" class="mr-1"
|
frontend/src/lib/Buttons/RoomsSelector.svelte
CHANGED
@@ -36,6 +36,7 @@
|
|
36 |
collapsed = true;
|
37 |
$page.url.searchParams.set('roomid', room.room_id);
|
38 |
window.location.search = `?${$page.url.searchParams.toString()}`;
|
|
|
39 |
}
|
40 |
</script>
|
41 |
|
|
|
36 |
collapsed = true;
|
37 |
$page.url.searchParams.set('roomid', room.room_id);
|
38 |
window.location.search = `?${$page.url.searchParams.toString()}`;
|
39 |
+
window.parent.postMessage({ queryString: `?${$page.url.searchParams.toString()}` }, '*');
|
40 |
}
|
41 |
</script>
|
42 |
|
frontend/src/lib/Buttons/ShareWithCommunity.svelte
CHANGED
@@ -3,6 +3,7 @@
|
|
3 |
import LoadingIcon from '$lib/Icons/LoadingIcon.svelte';
|
4 |
import { uploadImage } from '$lib/utils';
|
5 |
import { canvasEl, selectedRoomID } from '$lib/store';
|
|
|
6 |
|
7 |
let isUploading: boolean = false;
|
8 |
|
@@ -19,10 +20,17 @@
|
|
19 |
}
|
20 |
|
21 |
async function createCommunityPost(canvasBlob: Blob) {
|
22 |
-
const canvasURL = await uploadImage(canvasBlob,
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
const canvasImage = `<img src="${canvasURL.url}" style="width:100%" width="1000" height="1000">`;
|
24 |
const descriptionMd = `#### Stable Diffusion Multiplayer:
|
25 |
-
|
|
|
26 |
<div style="display: flex; overflow: scroll; column-gap: 0.75rem;">
|
27 |
${canvasImage}
|
28 |
</div>`;
|
@@ -41,12 +49,12 @@ ${canvasImage}
|
|
41 |
|
42 |
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
43 |
<div
|
44 |
-
class="text-
|
45 |
on:click={handleClick}
|
46 |
title="Share with community"
|
47 |
>
|
48 |
{#if isUploading}
|
49 |
-
<LoadingIcon classList={'animate-spin max-w-[25px]'} />
|
50 |
{:else}
|
51 |
<IconCommunity />
|
52 |
{/if}
|
|
|
3 |
import LoadingIcon from '$lib/Icons/LoadingIcon.svelte';
|
4 |
import { uploadImage } from '$lib/utils';
|
5 |
import { canvasEl, selectedRoomID } from '$lib/store';
|
6 |
+
import { nanoid } from 'nanoid';
|
7 |
|
8 |
let isUploading: boolean = false;
|
9 |
|
|
|
20 |
}
|
21 |
|
22 |
async function createCommunityPost(canvasBlob: Blob) {
|
23 |
+
const canvasURL = await uploadImage(canvasBlob, {
|
24 |
+
prompt: 'canvas',
|
25 |
+
position: { x: 0, y: 0 },
|
26 |
+
date: new Date().getTime(),
|
27 |
+
id: nanoid(),
|
28 |
+
room: $selectedRoomID || 'default'
|
29 |
+
});
|
30 |
const canvasImage = `<img src="${canvasURL.url}" style="width:100%" width="1000" height="1000">`;
|
31 |
const descriptionMd = `#### Stable Diffusion Multiplayer:
|
32 |
+
### [${$selectedRoomID}](https://huggingface.co/spaces/huggingface-projects/stable-diffusion-multiplayer?roomid=${$selectedRoomID})
|
33 |
+
|
34 |
<div style="display: flex; overflow: scroll; column-gap: 0.75rem;">
|
35 |
${canvasImage}
|
36 |
</div>`;
|
|
|
49 |
|
50 |
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
51 |
<div
|
52 |
+
class="text-xs font-mono flex items-center justify-center bg-black gap-x-1 rounded-xl cursor-pointer px-2 py-1"
|
53 |
on:click={handleClick}
|
54 |
title="Share with community"
|
55 |
>
|
56 |
{#if isUploading}
|
57 |
+
<LoadingIcon classList={'animate-spin max-w-[25px] text-white'} />
|
58 |
{:else}
|
59 |
<IconCommunity />
|
60 |
{/if}
|
frontend/src/lib/Menu.svelte
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
import RoomsSelector from '$lib/Buttons/RoomsSelector.svelte';
|
4 |
import AboutButton from '$lib/Buttons/AboutButton.svelte';
|
5 |
import { toggleAbout } from '$lib/store';
|
6 |
-
|
7 |
// const broadcast = useBroadcastEvent();
|
8 |
|
9 |
const dispatch = createEventDispatcher();
|
@@ -14,12 +14,17 @@
|
|
14 |
<svelte:window
|
15 |
on:keyup|preventDefault|stopPropagation={(e) => e.key === 'Enter' && dispatch('prompt')}
|
16 |
/>
|
17 |
-
<div class="flex flex-col md:flex-row items-center justify-between px-4 md:px-12 gap-
|
18 |
-
<
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
|
|
|
|
|
|
|
|
|
|
23 |
|
24 |
<button
|
25 |
on:click={() => dispatch('prompt')}
|
|
|
3 |
import RoomsSelector from '$lib/Buttons/RoomsSelector.svelte';
|
4 |
import AboutButton from '$lib/Buttons/AboutButton.svelte';
|
5 |
import { toggleAbout } from '$lib/store';
|
6 |
+
import ShareWithCommunity from '$lib/Buttons/ShareWithCommunity.svelte';
|
7 |
// const broadcast = useBroadcastEvent();
|
8 |
|
9 |
const dispatch = createEventDispatcher();
|
|
|
14 |
<svelte:window
|
15 |
on:keyup|preventDefault|stopPropagation={(e) => e.key === 'Enter' && dispatch('prompt')}
|
16 |
/>
|
17 |
+
<div class="flex flex-col md:flex-row items-center justify-between px-4 md:px-12 gap-3 md:gap-0">
|
18 |
+
<div class="flex flex-col justify-center items-center">
|
19 |
+
<AboutButton
|
20 |
+
on:click={() => {
|
21 |
+
$toggleAbout = !$toggleAbout;
|
22 |
+
}}
|
23 |
+
/>
|
24 |
+
<div class="order-last max-w-[20ch]">
|
25 |
+
<ShareWithCommunity />
|
26 |
+
</div>
|
27 |
+
</div>
|
28 |
|
29 |
<button
|
30 |
on:click={() => dispatch('prompt')}
|
frontend/src/lib/PaintFrame.svelte
CHANGED
@@ -7,7 +7,7 @@
|
|
7 |
import { round } from '$lib/utils';
|
8 |
|
9 |
import type { ZoomTransform } from 'd3-zoom';
|
10 |
-
import { onMount, createEventDispatcher
|
11 |
|
12 |
import { useMyPresence } from '$lib/liveblocks';
|
13 |
import { canvasEl, maskEl, loadingState, isRenderingCanvas } from '$lib/store';
|
@@ -272,16 +272,17 @@
|
|
272 |
>
|
273 |
{#if !isLoading}
|
274 |
<div class="mx-4 flex flex-col gap-2">
|
275 |
-
|
|
|
276 |
on:click={() => dispatch('prompt')}
|
277 |
class="w-10 h-10 bg-blue-600 hover:saturate-150 shadow-2xl shadow-blue-500 rounded-lg flex items-center justify-center text-3xl"
|
278 |
>
|
279 |
π
|
280 |
-
</button>
|
281 |
<button
|
282 |
title="Draw your custom mask on the frame"
|
283 |
on:click={toggleDrawMask}
|
284 |
-
class="w-10 h-10 bg-blue-600 hover:saturate-
|
285 |
>
|
286 |
<svg class="text-white" width="1em" height="1em" viewBox="0 0 100 100"
|
287 |
><path
|
|
|
7 |
import { round } from '$lib/utils';
|
8 |
|
9 |
import type { ZoomTransform } from 'd3-zoom';
|
10 |
+
import { onMount , createEventDispatcher} from 'svelte';
|
11 |
|
12 |
import { useMyPresence } from '$lib/liveblocks';
|
13 |
import { canvasEl, maskEl, loadingState, isRenderingCanvas } from '$lib/store';
|
|
|
272 |
>
|
273 |
{#if !isLoading}
|
274 |
<div class="mx-4 flex flex-col gap-2">
|
275 |
+
<button
|
276 |
+
title="Click to prompt and paint"
|
277 |
on:click={() => dispatch('prompt')}
|
278 |
class="w-10 h-10 bg-blue-600 hover:saturate-150 shadow-2xl shadow-blue-500 rounded-lg flex items-center justify-center text-3xl"
|
279 |
>
|
280 |
π
|
281 |
+
</button>
|
282 |
<button
|
283 |
title="Draw your custom mask on the frame"
|
284 |
on:click={toggleDrawMask}
|
285 |
+
class="w-10 h-10 bg-blue-600 hover:saturate-200 shadow-2xl shadow-blue-500 rounded-lg flex items-center justify-center text-3xl"
|
286 |
>
|
287 |
<svg class="text-white" width="1em" height="1em" viewBox="0 0 100 100"
|
288 |
><path
|
frontend/src/lib/types.ts
CHANGED
@@ -31,7 +31,7 @@ export type PromptImgObject = {
|
|
31 |
}
|
32 |
date: number;
|
33 |
id: string;
|
34 |
-
|
35 |
};
|
36 |
|
37 |
export type PromptImgKey = string;
|
|
|
31 |
}
|
32 |
date: number;
|
33 |
id: string;
|
34 |
+
room: string;
|
35 |
};
|
36 |
|
37 |
export type PromptImgKey = string;
|
frontend/src/lib/utils.ts
CHANGED
@@ -41,11 +41,6 @@ export async function uploadImage(imagBlob: Blob, params: {
|
|
41 |
|
42 |
const formData = new FormData()
|
43 |
formData.append('file', file)
|
44 |
-
formData.append('prompt', params.prompt)
|
45 |
-
formData.append('id', params.id)
|
46 |
-
formData.append('position', JSON.stringify(params.position))
|
47 |
-
formData.append('room', params.room)
|
48 |
-
formData.append('date', JSON.stringify(params.date))
|
49 |
|
50 |
const response = await fetch(PUBLIC_API_BASE + "/uploadfile", {
|
51 |
method: 'POST',
|
|
|
41 |
|
42 |
const formData = new FormData()
|
43 |
formData.append('file', file)
|
|
|
|
|
|
|
|
|
|
|
44 |
|
45 |
const response = await fetch(PUBLIC_API_BASE + "/uploadfile", {
|
46 |
method: 'POST',
|
frontend/src/routes/+page.svelte
CHANGED
@@ -41,13 +41,17 @@
|
|
41 |
if (room && roomAvailable) {
|
42 |
$selectedRoomID = room.room_id;
|
43 |
const state = { roomid: room.room_id };
|
44 |
-
|
|
|
|
|
45 |
}
|
46 |
}
|
47 |
if (emptyRoom && !roomAvailable) {
|
48 |
selectedRoomID.set(emptyRoom.room_id);
|
49 |
const state = { roomid: emptyRoom.room_id };
|
50 |
-
|
|
|
|
|
51 |
}
|
52 |
loading = false;
|
53 |
return { rooms };
|
|
|
41 |
if (room && roomAvailable) {
|
42 |
$selectedRoomID = room.room_id;
|
43 |
const state = { roomid: room.room_id };
|
44 |
+
const queryString = '?' + new URLSearchParams(state).toString();
|
45 |
+
window.history.replaceState(null, '', queryString);
|
46 |
+
window.parent.postMessage({ queryString: queryString }, '*');
|
47 |
}
|
48 |
}
|
49 |
if (emptyRoom && !roomAvailable) {
|
50 |
selectedRoomID.set(emptyRoom.room_id);
|
51 |
const state = { roomid: emptyRoom.room_id };
|
52 |
+
const queryString = '?' + new URLSearchParams(state).toString();
|
53 |
+
window.history.replaceState(null, '', queryString);
|
54 |
+
window.parent.postMessage({ queryString: queryString }, '*');
|
55 |
}
|
56 |
loading = false;
|
57 |
return { rooms };
|