Replace Atmoshpere Input with Slider and Add lower bound to gravity

This commit is contained in:
Neshura 2024-05-23 17:12:11 +02:00
parent f85faeb6ad
commit 6c39b77949
Signed by: Neshura
GPG key ID: B6983AAA6B9A7A6C
9 changed files with 123 additions and 33 deletions

View file

@ -25,7 +25,7 @@
}, },
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"bits-ui": "^0.21.8", "bits-ui": "^0.21.9",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"cmdk-sv": "^0.0.17", "cmdk-sv": "^0.0.17",
"svelte-radix": "^1.1.0", "svelte-radix": "^1.1.0",

View file

@ -0,0 +1,26 @@
<svelte:options runes />
<script lang="ts">
import {Label} from "$lib/components/ui/label";
import {Slider} from "$lib/components/ui/slider";
import {Localization} from "$lib/constants";
let { i18n = new Localization("en-GB"), value = $bindable() } = $props();
let array = $derived([value * 100])
let valid = $derived(typeof value !== "undefined");
function handleChange(change: number) {
value = change / 100;
}
</script>
{#if valid}
<Label for="atmosDensity">{i18n.localize("atmosDensity")} ({(value * 100).toFixed(0)}%)</Label>
<div class="flex gap-2">
<Label for="atmosDensity">0%</Label>
<Slider id="atmosDensity" value={array} onValueChange={handleChange} min={0} max={100} step={1} />
<Label>100%</Label>
</div>
{/if}

View file

@ -47,6 +47,7 @@
{#if valid} {#if valid}
<div class="flex flex-col flex-wrap gap-3 max-w-fit place-self-center items-center"> <div class="flex flex-col flex-wrap gap-3 max-w-fit place-self-center items-center">
<div>
<DropdownMenu.Root> <DropdownMenu.Root>
<DropdownMenu.Trigger> <DropdownMenu.Trigger>
<Button variant="secondary">{i18n.localize(name)}</Button> <Button variant="secondary">{i18n.localize(name)}</Button>
@ -59,7 +60,8 @@
</DropdownMenu.RadioGroup> </DropdownMenu.RadioGroup>
</DropdownMenu.Content> </DropdownMenu.Content>
</DropdownMenu.Root> </DropdownMenu.Root>
<Button class="bg-primary max-w-fit" onclick={() => onAddInventory(construct())}>{i18n.localize("addInventory")}</Button> </div>
<Button class="bg-primary max-w-fit" onmousedown={() => onAddInventory(construct())}>{i18n.localize("addInventory")}</Button>
</div> </div>
{:else} {:else}
<p>Invalid Props</p> <p>Invalid Props</p>

View file

@ -108,7 +108,7 @@
</DropdownMenu.Content> </DropdownMenu.Content>
</DropdownMenu.Root> </DropdownMenu.Root>
</div> </div>
<Button vclass="bg-primary max-w-fit" onclick={() => onAddThruster(construct())}>{i18n.localize("addThruster")}</Button> <Button vclass="bg-primary max-w-fit" onmousedown={() => onAddThruster(construct())}>{i18n.localize("addThruster")}</Button>
{:else} {:else}
<p>Invalid Props</p> <p>Invalid Props</p>
{/if} {/if}

View file

@ -0,0 +1,26 @@
<svelte:options runes />
<script lang="ts">
import {Localization, weightConversion} from "$lib/constants";
let { i18n = new Localization("en-GB"), maxWeight, maxVehicleWeight } = $props();
let valid = $derived.by(() => {
let valids = [];
valids[0] = typeof maxWeight !== "undefined";
valids[1] = typeof maxVehicleWeight !== "undefined";
return !valids.includes(false);
});
</script>
{#if valid}
<div class="flex gap-2">
<p>{i18n.localize("liftableVehcileWeight")}:</p>
{#if maxVehicleWeight < 0}
<p class="text-destructive">{weightConversion(i18n, maxVehicleWeight)}</p>
{:else}
<p>{weightConversion(i18n, maxVehicleWeight)}</p>
{/if}
</div>
<p>{i18n.localize("liftableWeight")}: {weightConversion(i18n, maxWeight)}</p>
{/if}

View file

@ -0,0 +1,7 @@
import Root from "./slider.svelte";
export {
Root,
//
Root as Slider,
};

View file

@ -0,0 +1,27 @@
<script lang="ts">
import { Slider as SliderPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
type $$Props = SliderPrimitive.Props;
let className: $$Props["class"] = undefined;
export let value: $$Props["value"] = [0];
export { className as class };
</script>
<SliderPrimitive.Root
bind:value
class={cn("relative flex w-full touch-none select-none items-center", className)}
{...$$restProps}
let:thumbs
>
<span class="relative h-1.5 w-full grow overflow-hidden rounded-full bg-primary/20">
<SliderPrimitive.Range class="absolute h-full bg-primary" />
</span>
{#each thumbs as thumb}
<SliderPrimitive.Thumb
{thumb}
class="block h-4 w-4 rounded-full border border-primary/50 bg-background shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50"
/>
{/each}
</SliderPrimitive.Root>

View file

@ -21,6 +21,10 @@
import NewInventory from "$lib/components/NewInventory.svelte"; import NewInventory from "$lib/components/NewInventory.svelte";
import {Inventory} from "$lib/containers.svelte"; import {Inventory} from "$lib/containers.svelte";
import InventoryList from "$lib/components/InventoryList.svelte"; import InventoryList from "$lib/components/InventoryList.svelte";
import type {Thruster} from "$lib/thruster.svelte";
import {Slider} from "$lib/components/ui/slider";
import Atmosphere from "$lib/components/Atmosphere.svelte";
import WeightOutputSegment from "$lib/components/WeightOutputSegment.svelte";
const STORAGE_VERSION = "2"; const STORAGE_VERSION = "2";
let i18n = $state(new Localization("en-GB")); let i18n = $state(new Localization("en-GB"));
@ -67,6 +71,7 @@
let maxVehicleWeight: number = $derived(maxWeight - ship.getTotalVolume(inventoryMultiplier) * material.density) let maxVehicleWeight: number = $derived(maxWeight - ship.getTotalVolume(inventoryMultiplier) * material.density)
function addInventory(newInventory: Inventory) { function addInventory(newInventory: Inventory) {
console.log("triggered")
ship.addInventory(newInventory); ship.addInventory(newInventory);
} }
@ -82,6 +87,12 @@
ship.removeThruster(index); ship.removeThruster(index);
} }
function handleGravityChange() {
if (gravity <= 0) {
gravity = 0;
}
}
onMount(() => { onMount(() => {
if (navigator) { if (navigator) {
i18n.language = navigator.language; i18n.language = navigator.language;
@ -157,24 +168,23 @@
{#if ship.grid === size} {#if ship.grid === size}
<Button class="bg-primary">{i18n.localize(size)}</Button> <Button class="bg-primary">{i18n.localize(size)}</Button>
{:else} {:else}
<Button variant="secondary" onclick={() => ship.grid = size}>{i18n.localize(size)}</Button> <Button variant="secondary" onmousedown={() => ship.grid = size}>{i18n.localize(size)}</Button>
{/if} {/if}
{/each} {/each}
</div> </div>
<Label for="gravity">{i18n.localize("gravity")}</Label> <Label for="gravity">{i18n.localize("gravity")}</Label>
<Input type="number" step="0.01" id="gravity" bind:value={gravity}/> <Input type="number" step="0.01" id="gravity" bind:value={gravity} onchange={(change) => {handleGravityChange(change)}}/>
<Label for="density">{i18n.localize("density")}</Label> <Label for="density">{i18n.localize("density")}</Label>
<div id="density" class="flex gap-2"> <div id="density" class="flex gap-2">
{#each Object.values(CargoMaterial) as value} {#each Object.values(CargoMaterial) as value}
{#if material === value} {#if material === value}
<Button class="bg-primary">{i18n.localize(value.name)}</Button> <Button class="bg-primary">{i18n.localize(value.name)}</Button>
{:else} {:else}
<Button variant="secondary" onclick={() => material = value}>{i18n.localize(value.name)}</Button> <Button variant="secondary" onmousedown={() => material = value}>{i18n.localize(value.name)}</Button>
{/if} {/if}
{/each} {/each}
</div> </div>
<Label for="atmosDensity">{i18n.localize("atmosDensity")}</Label> <Atmosphere bind:value={atmosphericDensity} />
<Input type="number" step="0.01" id="atmosDensity" bind:value={atmosphericDensity}/>
</Card.Content> </Card.Content>
</Card.Root> </Card.Root>
<Card.Root> <Card.Root>
@ -183,15 +193,7 @@
</Card.Header> </Card.Header>
<Card.Content class="flex flex-col gap-3"> <Card.Content class="flex flex-col gap-3">
<Separator /> <Separator />
<div class="flex gap-2"> <WeightOutputSegment {i18n} maxWeight={maxWeight} maxVehicleWeight="{maxVehicleWeight}" />
<p>{i18n.localize("liftableVehcileWeight")}:</p>
{#if maxVehicleWeight < 0}
<p class="text-destructive">{weightConversion(i18n, maxVehicleWeight)}</p>
{:else}
<p>{weightConversion(i18n, maxVehicleWeight)}</p>
{/if}
</div>
<p>{i18n.localize("liftableWeight")}: {weightConversion(i18n, maxWeight)}</p>
<Separator /> <Separator />
<p>{i18n.localize("fuels")}: <p>{i18n.localize("fuels")}:
{ship.getFuelTypes().map((fuel) => i18n.localize(fuel.name)).join(", ") } {ship.getFuelTypes().map((fuel) => i18n.localize(fuel.name)).join(", ") }

View file

@ -494,10 +494,10 @@ binary-extensions@^2.0.0:
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522"
integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==
bits-ui@^0.21.8: bits-ui@^0.21.9:
version "0.21.8" version "0.21.9"
resolved "https://registry.yarnpkg.com/bits-ui/-/bits-ui-0.21.8.tgz#623127b87558c9943c00393cb5969c1ae7ca7cfa" resolved "https://registry.yarnpkg.com/bits-ui/-/bits-ui-0.21.9.tgz#3e9ca44445a1f9a431783e2a7269de220f6dd3ec"
integrity sha512-fr++Gf//41w9/Td5r1SfaeA/XXv5YEOw3LFY7JVH+eAbi7RzNqf7Xy8BS/W8HXfRqlsu1ReFgZ7ZZ4DbrP4HwQ== integrity sha512-tMoHi2QbsNKJsPDoXGi07OMx6F8LVMSNYMMcntFX4fPPvy+SJSeZYOKlBMmneiSg7smpWzg+h20q0q01OvyxZQ==
dependencies: dependencies:
"@internationalized/date" "^3.5.1" "@internationalized/date" "^3.5.1"
"@melt-ui/svelte" "0.76.2" "@melt-ui/svelte" "0.76.2"