Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion app/javascript/scss/elements/_warning.scss
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
&--orange,
&--warning {
background: $orange;
font-size: $font-size-small;
}

p {
Expand Down
6 changes: 6 additions & 0 deletions app/javascript/scss/utilities/_text.scss
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@
}
}

.text-truncate {
overflow-x: hidden;
text-overflow: ellipsis;
display: inline-block;
}

.text-small {
font-size: $font-size-small;
line-height: 1.35em;
Expand Down
8 changes: 8 additions & 0 deletions app/javascript/src/components/editor/Editor.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import Bugsnag from "@components/Bugsnag.svelte"
import EyeIcon from "@components/icon/Eye.svelte"
import Logs from "@components/editor/Logs.svelte"
import { fetchProject } from "@src/utils/project"

export let bugsnagApiKey = ""
export let _isSignedIn = false
Expand Down Expand Up @@ -60,6 +61,12 @@
loading = false
})

$: if ($currentProjectUUID && !$projects.some(({ uuid }) => uuid === $currentProjectUUID)) {
fetchProject($currentProjectUUID).then((currentProject) => {
$projects.push(currentProject)
})
}
Comment on lines +64 to +68
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer $projects to not ever contain a project that is not owned by the user

Copy link
Contributor Author

@netux netux Mar 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you be okay with at least renaming it $user/ownProjects? Its naming is a bit vague otherwise.

I also noticed a lot of checks for $currentProject?.is_owner, making it seem like we could have a project in $projects that could be owned by some other user ($currentProject derives from $projects).


function parseKeywords() {
const { events, values, actions, constants, heroes, maps } = data

Expand Down Expand Up @@ -196,6 +203,7 @@
if (!data) throw Error("No projects data was returned.")

return JSON.parse(data)
.map((project) => ({ ... project, is_owner: true }))
})
.catch(error => {
alert(`Something went wrong while loading, please try again. ${error}`)
Expand Down
6 changes: 3 additions & 3 deletions app/javascript/src/components/editor/EditorActions.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

<div class="editor__actions" transition:fly={{ y: -10, duration: 200 }}>
{#if $currentProjectUUID && !$currentProject?.is_owner && !$isMobile}
<div class="warning warning--orange ml-1/8 br-1 align-self-center">
You do not own this project and can not save
<div class="warning text-small ml-1/8 br-1 align-self-center">
You do not own this project
</div>
{/if}

Expand Down Expand Up @@ -68,7 +68,7 @@
</div>
{/if}

{#if $isSignedIn && $currentProject?.is_owner}
{#if $isSignedIn}
<Save />
{/if}
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
loading = true

const data = await createProject(value)
if (data != "error") {
if (data) {
modal.close()
if (data) setUrl(data.uuid)
setUrl(data.uuid)
}

loading = false
Expand Down Expand Up @@ -47,7 +47,7 @@

<Modal flush>
{#if !$isSignedIn}
<div class="warning warning--orange">
<div class="warning warning--orange text-small">
You are not signed in and this is for demonstration purposes only. Any changes you make will not be saved.
</div>
{/if}
Expand Down
73 changes: 40 additions & 33 deletions app/javascript/src/components/editor/ProjectsDropdown.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script>
import SearchObjects from "@components/editor/SearchObjects.svelte"
import { projects, currentProject, isSignedIn, isMobile, modal } from "@stores/editor"
import { projects, currentProject, isSignedIn, isMobile, modal, currentProjectUUID } from "@stores/editor"
import { getSaveContent } from "@utils/editor"
import { createProject, destroyCurrentProject, fetchProject, setUrl } from "@utils/project"
import { escapeable } from "@components/actions/escapeable"
Expand All @@ -12,16 +12,18 @@
let loading = false
let active = false
let showProjectSettings = false
let filteredProjects = $projects
let ownProjects = []
let filteredProjects = []

$: ownProjects = $projects.filter(({ is_owner }) => is_owner)
Comment on lines +15 to +18
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really want the state of projects that are not part of your project to be handled in the projects dropdown, I think it would make more sense somewhere else.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point.
Considering my comment above, what do you think about renaming $projects to $user/ownProjects, and having a $projects that contains a cache of all known projects (essentially what I do here with the current $projects)?

Then $user/ownProjects can derive from $projects, filtering out any projects that have is_owner set to false.

$: limit = $isMobile ? 5 : 25

onMount(() => {
const urlParams = new URLSearchParams(window.location.search)
const uuid = urlParams.get("uuid")

if (uuid) getProject(uuid)
else if ($projects.length) getProject($projects[0].uuid)
else if (ownProjects.length) getProject(ownProjects[0].uuid)
})

async function getProject(uuid) {
Expand Down Expand Up @@ -52,7 +54,8 @@
loading = true

const content = getSaveContent()
const data = await createProject($currentProject.title + " (Copy)", content)

const data = await createProject(`${$currentProject.title} (Copy)`, content)
if (data) {
setUrl(data.uuid)
await fetchProject(data.uuid)
Expand All @@ -63,39 +66,41 @@
}
</script>

<div class="dropdown" use:outsideClick on:outsideClick={() => active = false}>
<div class="dropdown" style:max-width="200px" use:outsideClick on:outsideClick={() => active = false}>
<button class="form-select pt-1/8 pb-1/8 pl-1/4 text-left" on:click|stopPropagation={() => active = !active} style:min-width="{$isMobile ? 75 : 200}px" disabled={loading}>
{#if loading}
Loading...
{:else if $currentProject}
<span class="w-100 text-truncate nowrap">{$currentProject.title}</span>
{:else}
{$currentProject?.title.substring(0, limit).trim() || "Select a project..."}{#if $currentProject?.title.length > limit}...{/if}
Select a project...
{/if}
</button>

{#if active}
<div transition:fly={{ duration: 150, y: 20 }} use:escapeable on:escape={() => active = false} class="dropdown__content dropdown__content--left block w-100" style:min-width="200px">
<div class="pl-1/8 pr-1/8">
<SearchObjects objects={$projects} bind:filteredObjects={filteredProjects} />
<SearchObjects objects={ownProjects} bind:filteredObjects={filteredProjects} />
</div>

<hr />

{#each filteredProjects as project (project.uuid)}
<button class="dropdown__item" animate:flip={{ duration: 100 }} on:click={() => getProject(project.uuid)}>
<button class="dropdown__item text-truncate" animate:flip={{ duration: 100 }} on:click={() => getProject(project.uuid)}>
{project.title}
</button>
{/each}

{#if $projects?.length && !filteredProjects.length}
{#if ownProjects?.length && !filteredProjects.length}
<em class="block text-dark text-small pl-1/8 pr-1/8">No projects match your search.</em>
{/if}

{#if $projects?.length}
{#if ownProjects?.length}
<hr />
{/if}

<div class="p-1/4">
{#if !$projects?.length}
{#if !ownProjects?.length}
<em class="text-small block mb-1/4">Create a new project to get started.</em>
{/if}
<button class="button button--small w-100" on:click={() => {
Expand All @@ -109,26 +114,28 @@
{/if}
</div>

{#if $isSignedIn && $currentProject?.is_owner && !loading}
<div class="dropdown" use:outsideClick on:outsideClick={() => showProjectSettings = false}>
<button class="w-auto text-base ml-1/8" on:click|stopPropagation={() => showProjectSettings = !showProjectSettings}>
Edit
</button>

{#if showProjectSettings}
<div transition:fly={{ duration: 150, y: 20 }} class="dropdown__content dropdown__content--left block w-100" style="width: 200px">
<button class="dropdown__item" on:click={() => modal.show("create-project", { type: "rename" })}>
Rename
</button>

<button class="dropdown__item" on:click={duplicateProject}>
Duplicate
</button>

<button class="dropdown__item text-red" on:click={destroyProject}>
Destroy
</button>
</div>
{/if}
</div>
{#if $isSignedIn && !loading}
{#if $currentProject?.is_owner}
<div class="dropdown" use:outsideClick on:outsideClick={() => showProjectSettings = false}>
<button class="w-auto text-base ml-1/8" on:click|stopPropagation={() => showProjectSettings = !showProjectSettings}>
Edit
</button>

{#if showProjectSettings}
<div transition:fly={{ duration: 150, y: 20 }} class="dropdown__content dropdown__content--left block w-100" style="width: 200px">
<button class="dropdown__item" on:click={() => modal.show("create-project", { type: "rename" })}>
Rename
</button>

<button class="dropdown__item" on:click={() => duplicateProject()}>
Duplicate
</button>

<button class="dropdown__item text-red" on:click={destroyProject}>
Destroy
</button>
</div>
{/if}
</div>
{/if}
{/if}
Loading
Loading