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 };
|