Compare commits

...

3 Commits

Author SHA1 Message Date
valerio
9198b601be FEAT: Version Selection 2026-04-29 13:57:44 +02:00
valerio
3fee3fded9 FEAT: Loding screen
Some checks failed
publish / publish-tauri (, ubuntu-22.04) (push) Failing after 4m4s
2026-03-30 17:08:04 +02:00
valerio
a3bf261682 FEAT: Splash Screen
todo: loading status and percent
2026-03-23 19:57:20 +01:00
6 changed files with 133 additions and 47 deletions

View File

@ -1,6 +1,6 @@
{
"name": "smoothie",
"version": "0.1.0",
"version": "0.1.1",
"description": "",
"type": "module",
"scripts": {

View File

@ -2,6 +2,13 @@
import VersionCard from './VersionCard.svelte';
import { send, receive } from '$lib/transition.js';
import { flip } from 'svelte/animate';
import { selectedVersionStore } from '$lib/library.js';
let selectedVersion = $state(null);
selectedVersionStore.subscribe((version) => {
selectedVersion = version;
});
let { installedVersions } = $props();
import '@webtui/css/base.css';
@ -22,7 +29,7 @@
in:receive={{ key: version.version }}
out:send={{ key: version.version }}
>
<VersionCard {version} />
<VersionCard {version} {selectedVersion} />
</div>
{/each}
{:else}
@ -40,7 +47,7 @@
in:receive={{ key: version.version }}
out:send={{ key: version.version }}
>
<VersionCard {version} />
<VersionCard {version} {selectedVersion} />
</div>
{/each}
</div>

View File

@ -0,0 +1,37 @@
<script>
import { load } from '@tauri-apps/plugin-store';
let { loadingState } = $props();
</script>
<div class="splash">
<div class="spinner">
<pre class="monospace">
▄▄▄▄▄
██▀▀▀▀█▄ █▄ █▄
▀██▄ ▄▀ ▄ ▄██▄██ ▀▀
▀██▄▄ ███▄███▄ ▄███▄ ▄███▄ ██ ████▄ ██ ▄█▀█▄
▄ ▀██▄ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██▄█▀
▀██████▀▄██ ██ ▀█▄▀███▀▄▀███▀▄██▄██ ██▄██▄▀█▄▄▄
</pre>
</div>
<p>{loadingState}</p>
</div>
<style>
.splash {
align-items: center;
justify-content: center;
flex-direction: column;
display: flex;
width: 100%;
height: 100%;
}
.spinner {
}
.monospace {
font-family: monospace;
color: var(--black);
letter-spacing: 1px;
}
</style>

View File

@ -4,15 +4,18 @@
deleteVersion,
launchBlenderVersion,
toggleFavourite,
registerVersion
registerVersion,
selectVersion
} from '$lib/library';
import Button from '$lib/components/Button.svelte';
import Menu from '$lib/components/Menu.svelte';
import { show } from '$lib/components/Dialog.svelte';
let { version } = $props();
let { version, selectedVersion } = $props();
let popup = $state();
let selected = $derived(version.version === selectedVersion?.version);
async function handleDelete() {
const prompt = await show({
title: 'Delete',
@ -41,7 +44,16 @@
<Popup bind:this={popup} content="Version {version.version} is now the default on your system"
></Popup>
<div id="card">
<div
role="button"
tabindex="0"
onkeydown={() => {}}
onclick={async () => {
await selectVersion(version);
}}
id="card"
class:selected
>
<div class="row">
{version.version}
<Button style="iconbutton" onclick={() => toggleFavourite(version)}
@ -93,11 +105,13 @@
width: 100%;
min-width: 170px;
max-width: 200px;
background-color: var(--white);
border-radius: 5px;
background-color: var(--light);
padding: 1rem;
}
#card.selected {
background-color: var(--light-accent);
}
.row {
display: flex;
align-items: center;

View File

@ -19,9 +19,14 @@ import { updateDownloadProgress } from './download';
* @property {Date} [installDate] - Installation date (if available)
*/
export const currentInstalledVersions = writable([]);
export const installedVersionsStore = writable([]);
export const selectedVersionStore = writable(null);
const favouritesStore = new LazyStore('versions.json');
export async function selectVersion(version) {
selectedVersionStore.set(version);
}
export async function generateVersionBanner(version) {
const bannerPath = `${version.path}/banner.png`;
if (await exists(bannerPath)) {
@ -200,7 +205,7 @@ export async function removeVersion(version) {
* @param {blenderVersion} version The version to toggle.
*/
export async function toggleFavourite(version) {
const versions = get(currentInstalledVersions);
const versions = get(installedVersionsStore);
console.log();
const versionObj = versions.find((v) => v.version === version.version);
if (versionObj) {
@ -208,7 +213,7 @@ export async function toggleFavourite(version) {
} else {
console.error('version not found', version);
}
currentInstalledVersions.set(versions);
installedVersionsStore.set(versions);
await favouritesStore.set(version.version, versionObj.favourite);
await favouritesStore.save();
}
@ -230,9 +235,9 @@ export async function deleteVersion(version) {
await favouritesStore.save();
// Update the current installed versions list
const versions = get(currentInstalledVersions);
const versions = get(installedVersionsStore);
const filteredVersions = versions.filter((v) => v.version !== version.version);
currentInstalledVersions.set(filteredVersions);
installedVersionsStore.set(filteredVersions);
console.log(`Successfully deleted version ${version.version}`);
} catch (error) {
@ -253,13 +258,13 @@ export async function getInstalledVersions() {
const settings = get(currentSettings);
const libraryDir = settings.libraryDir;
if (!libraryDir) {
currentInstalledVersions.set([]);
installedVersionsStore.set([]);
return [];
}
const blenderLibraryPath = await join(libraryDir, BASE_LIBRARY_DIR, 'blender');
if (!exists(blenderLibraryPath)) {
currentInstalledVersions.set([]);
installedVersionsStore.set([]);
return [];
}
@ -308,13 +313,13 @@ export async function getInstalledVersions() {
}
}
currentInstalledVersions.set(versions);
installedVersionsStore.set(versions);
cleanupOrphanedDesktopFiles(versions);
return versions;
} catch (error) {
console.error('Error getting installed versions:', error);
currentInstalledVersions.set([]);
installedVersionsStore.set([]);
return [];
}
}

View File

@ -1,33 +1,42 @@
<script>
import '@webtui/css/components/spinner.css';
import { setupTrayIcon } from '$lib/trayicon';
import { fade } from 'svelte/transition';
// LIBS
import { getVersion } from '@tauri-apps/api/app';
import { onMount } from 'svelte';
import { getSettings, currentSettings } from '$lib/settings.js';
import { fade } from 'svelte/transition';
import '@webtui/css/components/spinner.css';
// MODULES
import { setupTrayIcon } from '$lib/trayicon';
import { getSettings, currentSettings } from '$lib/settings';
import { getBlenderReleases, blenderReleases } from '$lib/blenderfetch';
import { getInstalledVersions, currentInstalledVersions } from '$lib/library.js';
import { getInstalledVersions, installedVersionsStore } from '$lib/library.js';
import { downloadTasksStore } from '$lib/download.js';
import Library from '$lib/components/Library.svelte';
import Download from '$lib/components/Download.svelte';
import Settings from '$lib/components/Settings.svelte';
import Popup from '$lib/components/Popup.svelte';
import Dialog from '$lib/components/Dialog.svelte';
import Splash from '$lib/components/Splash.svelte';
// states
let fadeInSettings = { duration: 100 };
let fadeOutSettings = { duration: 100, delay: fadeInSettings.duration };
let activeTab = 'library';
let blenderVersions = [];
let installedVersions = [];
let downloadTasks = [];
let settings = {};
let initialized = false;
let activeTab = $state('library');
let blenderVersions = $state([]);
let installedVersions = $state([]);
let downloadTasks = $state([]);
let settings = $state();
let initialized = $state(false);
let version = $state('');
let loadingState = $state('loading'); // load, update, initialized
function initStoresListeners() {
async function initStoresListeners() {
currentSettings.subscribe((value) => {
settings = value;
console.log('Loaded settings:', settings);
});
currentInstalledVersions.subscribe((value) => {
installedVersionsStore.subscribe((value) => {
installedVersions = value;
console.log('Loaded installed versions:', installedVersions);
});
@ -42,26 +51,20 @@
}
onMount(async () => {
const startTime = Date.now();
loadingState = 'Checking for Updates';
version = await getVersion();
loadingState = 'Loading Settings';
await getSettings();
loadingState = 'Fetching Blender Releases';
await getBlenderReleases();
loadingState = 'Loading your installs';
await getInstalledVersions();
loadingState = 'Setting up Tray';
await setupTrayIcon();
initStoresListeners();
const elapsed = Date.now() - startTime;
if (elapsed < 2000) {
initialized = true;
/* setTimeout(() => {
initialized = true;
}, 2000 - elapsed);*/
} else {
initialized = true;
}
//await getInstalledVersions();
//
loadingState = 'initializing';
await initStoresListeners();
await setTimeout(() => {}, 1000);
loadingState = 'initialized';
});
</script>
@ -69,7 +72,7 @@
<Dialog />
<div id="main">
{#if initialized}
{#if loadingState == 'initialized'}
<div class="tablist" role="tablist">
<div
role="tab"
@ -122,8 +125,11 @@
{/if}
</div>
</div>
<div class="version">v{version}</div>
{:else}
LOADING...
<div class="splash-wrapper" in:fade={{ duration: 100 }} out:fade={{ delay: 50, duration: 200 }}>
<Splash {loadingState} />
</div>
{/if}
</div>
@ -207,4 +213,21 @@
width: 100%;
height: 100%;
}
.version {
position: fixed;
bottom: 2rem;
right: 2rem;
z-index: 2;
text-align: right;
color: var(--light-accent);
}
.splash-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: var(--white);
z-index: 1;
}
</style>