Skip to content

Conversation

@ndom91
Copy link

@ndom91 ndom91 commented Nov 3, 2025

Hey man, was sooo happy to have found this when I got my niim labelmaker. As a web dev I want to help improve the UI, but first I figured this could use a nice little pass to ensure all eslint/prettier stuff is setup correctly and that all dependencies are up to date. Hope I haven't changed too much on you 😅

This PR does the following:

  • bump all dependencies
  • ensure prettier/eslint are up to date and installed correctly
  • format all files
  • Add and enable sveltekit in "single page app" mode (client-side only)

@MultiMote
Copy link
Owner

Wow, this PR is huge. I need some time to review it 😂

@MultiMote
Copy link
Owner

MultiMote commented Nov 3, 2025

Quick look:

  1. Do we really need sveltekit? This is single page app without routes and server features. Using SvelteKit here is overkill; we only need a library for building a graphical interface.
    One of my goals was to minimize dependencies, and now the project uses 411 dependencies instead of 265 🙂

  2. Text block uses default font on first load. When you modify text (change size, for example) it becomes normal.
    image

  3. Label saving to browser storage is now weird. Many labels saved, but one displayed.

  4. meta and some other tags in html template are missing.

@ndom91
Copy link
Author

ndom91 commented Nov 4, 2025

  1. We don't need sveltekit, no, I guess we really don't use any of the niceties it gives you here. I'll remove that .

  2. Good catch, will check that out.

3 and 4. I think I know what this is - will double check this as well and get back to you.

Thanks for the quick reply!

After this I'll try to give the UI some (conservative) love. Any ideas yourself or preferences?

@MultiMote
Copy link
Owner

Any ideas yourself or preferences?

Main goal is not make UI mobile-oriented 🙂
It should be comfortable both for PC and mobile users.
Currently my biggest pain is hi-res labels that not fit into screen. I think I should implement some pan-zoom functionality, but I am not ready to do that because it's complicated with fabric.js.

@MultiMote
Copy link
Owner

What about eslint and prettier - I prefer to make them optional (project README has line about that), but having configs for them.

@ndom91
Copy link
Author

ndom91 commented Nov 4, 2025

Hmm, so thats a bit awkward. Generally javascript projects have them on or off, both for the ease of contributing but also to standardize code style. Because if you allow it to be off sometimes then folks can and will just submit code in any style. That kind of defeats the purpose of having them all together. There are no post-commit hooks or anything like that that forces folks to use it in this PR - but it will set it up for (arguably the sane 😂) folks if they want.

Also the way it was currently setup would require someone to have prettier and eslint installed globally which is a big no-no

Regarding UI stuff - perfect, that's what I was thinking as well. Just some simple tweaks to make it more comfortable to use on the desktop first and foremost.

How attached areyou to the capacitor apk build? What do you think about shipping the web app as a progressive web app (PWA) so folks can "install" the web app on mobile devices?

@MultiMote
Copy link
Owner

MultiMote commented Nov 4, 2025

There are no post-commit hooks or anything like that that forces folks to use it in this PR - but it will set it up for (arguably the sane 😂) folks if they want.

Personally I am using IDE prettier extension and prettier config in project dir is enough.

Also the way it was currently setup would require someone to have prettier and eslint installed globally which is a big no-no

README entry is meant for installing eslint in the project directory, not globally.

Anyway, I am not very experienced web dev and if you sure that I need to include them as dependency, it is ok.

How attached areyou to the capacitor apk build? What do you think about shipping the web app as a progressive web app (PWA) so folks can "install" the web app on mobile devices?

It was done already if I understand correctly: niimblue.webmanifest.
What about APK - it more comfortable for some people.

@MultiMote MultiMote changed the base branch from main to svelte5 November 4, 2025 14:03
@ndom91
Copy link
Author

ndom91 commented Nov 6, 2025

Yeah so installing the prettier extension in effect installs it "globally" for you / the projects you open in VSCode. But, for example, anyone using another editor (i use vim for example) would want it to be installed "normally". I'd highly suggest going this route with eslint/prettier 👍

I was just curious about the capacitor stuff, i will make sure it stays then!

About PWA, you need more than just a manifest file afaik. I definitely couldn't install it on Vivaldi android (chrome 140) 😅 It's also missing a specific png img size apparently (https://www.pwabuilder.com/reportcard?site=https://niim.blue), but no worries. Not super important right now.

I'll remove Sveltekit and clean this up a bit further this weekend and we can go from there ❤️

@MultiMote
Copy link
Owner

It's also missing a specific png img size apparently

Fixed

@ndom91
Copy link
Author

ndom91 commented Nov 9, 2025

Okay, I've removed SvelteKit and addressed some of your feedback. To get to your last msg specifics:


Quick look:

  1. Do we really need sveltekit? This is single page app without routes and server features. Using SvelteKit here is overkill; we only need a library for building a graphical interface.
    One of my goals was to minimize dependencies, and now the project uses 411 dependencies instead of 265 🙂

Don't let JS hate on the internet get to you btw 😅, I see you're active in many non-web dev areas of software development. Of course keeping dependencies low generally is not a bad goal, but almost none of these would have gotten shipped to the client. We had basically only added @sveltejs/kit which gets compiled away for the mostt part during the build process anyway. Bigger additions to the client JS bundle size are things like bootstrap and material-icons.

I'd recommend taking a look at something like Anthony Fu's node-modules-inspector if you're curious. Again, this is purely node_modules / dev install size though. Not to be confused with client served bundle size.

npx node-modules-inspector

For client-side bundle size, I like vite-bundle-analyzer because it can also be run directly via npx, no install necessary.

npx vite-bundle-analyzer

They both then open a nice UI in the browser locally to inspect things.

  1. Text block uses default font on first load. When you modify text (change size, for example) it becomes normal.
    image

Not sure exactly what you mean here. When I load it during dev (and clear all cache / localstorage / etc.), I get NotoSans by default and all other font things seem to work. Can you help me understand what the issue is here?

  1. Label saving to browser storage is now weird. Many labels saved, but one displayed.

Can you help me reproduce this? Maybe was an issue only when we had sveltekit on. It seems to work as expected now

CleanShot 2025-11-09 at 14 48 52
  1. meta and some other tags in html template are missing.

SvelteKit would add those in the build process via stuff like this (see screenshot), you shouldn't put them in the root app.html itself, because we'd also want to potentially change them (based on the page you're on, or some page state, etc.). Anyway, I've removed SvelteKit now so we will have to handle that manually again.

CleanShot 2025-11-09 at 14 47 50

@MultiMote
Copy link
Owner

Can you help me reproduce this? Maybe was an issue only when we had sveltekit on. It seems to work as expected now

Still broken. Press save multiple times. Do not change the name.
"make default" also broken. "X" does not appear.

Your branch:

vivaldi_hrHmkVHsiZ.mp4

Main branch:

vivaldi_zODTANFapH.mp4

@MultiMote
Copy link
Owner

Not sure exactly what you mean here. When I load it during dev (and clear all cache / localstorage / etc.), I get NotoSans by default and all other font things seem to work. Can you help me understand what the issue is here?

It fixed by reverting font preload meta tags (below <!-- Preload fonts to make canvas.js happy --> comment).

@ndom91
Copy link
Author

ndom91 commented Nov 10, 2025

Okay I've removed those font preload tags and updated the package-lock, forgot to commit that after sveltekit removal.

Regarding the label behavior. It's because the key for that {#each } block was the label.title, which if you hit save on the same label multiple times will result in multiple labels with the same title and svelte not being able to differentiate them.

Unfortunately there isn't any globally unique field on labels like an id or something like that. What do you think of saving the localstorage key as id: key on the element as well?

@MultiMote
Copy link
Owner

MultiMote commented Nov 11, 2025

Okay I've removed those font preload tags and updated the package-lock, forgot to commit that after sveltekit removal.

Why? They're actually necessary to fix the problem above😮
When you restored original index.html, everything started working as it should.

Unfortunately there isn't any globally unique field on labels like an id or something like that. What do you think of saving the localstorage key as id: key on the element as well?

We can use timestamp field as temporary solution (will not work if labels saved in one second). Later we can pass localstorage key as element key.

Also what the purpose of [key: string]: any? Why we not declare "class" prop explicitly?

interface Props {
    [key: string]: any
}

Also build fails

image

Also static resourses are now not included in the build/dev

image

Can you also tell what the purpose of modifications in tsconfig.json?

@ndom91
Copy link
Author

ndom91 commented Nov 11, 2025

Ahh i thought you were telling me you tried it and I should remove the font meta tags 😂

You can't use "class" as prop because that's a keyword in js (i.e. for actual classes, so had to rename to className in the destructuring)

Time stamp isn't great as key, as you mentioned, but maybe best for now

Okay, let's get this finished.. Will check the remaining comments and test that everything works as expected.

@MultiMote
Copy link
Owner

You can't use "class" as prop because that's a keyword in js (i.e. for actual classes, so had to rename to className in the destructuring)

image

Is this bad? No errors thrown.

@ndom91
Copy link
Author

ndom91 commented Nov 12, 2025

I've updated the class / [key: string] type issues. The issue isn't in defining a prop / type called "class" but using that in svelte then. Svelte will complain and give you cryptic error messages about cant find variable or something like that. That's why I've renamed it className in the destructuring from $props.

Which btw that is new Svelte 5 sync, the const { onItemDelete } = $props() syntax. Is a lot easier to reason about rather than export let for each prop, one per line, imo.

Some of the tsconfig.json changes (like the extends was left-over from sveltekit. I've removed that now. The other change there, for example the paths ones, is so that you can use those as "shortcuts" to import stuff anywhere in the codebase. So for example, we have this entry in tsconfig.json now: "$components/*": ["src/components/*"]. That means that anywhere in your app now, you can import a component via that path. See for example in dashboard.svelte:

CleanShot 2025-11-12 at 19 59 01

This way you never have to worry about figuring out ../../../ (how many directories do I go up? And then what is the path of hte file I want again?)

To your last point, I also renamed static/ back to public/ and it copies your .ico, webmanifest, etc. into dist on build now too 👍

@ndom91
Copy link
Author

ndom91 commented Nov 12, 2025

Also just noticed that that PWABuilder site I linked earlier has a function to take your PWA and generate bundles to publish to the Microsoft Store, Apple App Store and Google Play Store 🤯.

I tested the Play Store functionality with another side project of mine and it does successfully generate an APK that basically just wraps your PWA in a native app "cloak" and then provides all the config and what not you'd need to publish it on the Play Store too.

Very cool, figured it might be of interest to you 👍

https://www.pwabuilder.com/

CleanShot 2025-11-12 at 20 16 25

Copy link
Owner

@MultiMote MultiMote left a comment

Choose a reason for hiding this comment

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

  • index.html still not reverted
  • locale files still not reverted / excluded from formatting
  • project uses npm, not pnpm, remove pnpm-lock.
  • svelte.config.js: type comment should be /** @type {import("@sveltejs/vite-plugin-svelte").SvelteConfig} */
  • there are lot of eslint errors about #each keys
  • I think we need to disable build warnings about non-labeled close buttons:
const config = {
    preprocess: vitePreprocess(),
    compilerOptions: {
        warningFilter: (warning) => {
            return warning.code !== 'a11y_consider_explicit_label';
        }
    }
};
  • You need to merge upstream changes.

Still, it wasn't the best idea to combine migration, refactoring, and formatting into a single pull request 😔

@ndom91
Copy link
Author

ndom91 commented Nov 13, 2025

Yeah we'll get through them, I've fixed most of the above.

The lint issues are stuff you should probably address tbh. Like the each having key ones - otherwise handling objects in each blocks can easily get the dom confused.

Ofc feel free to add the ignore of the button label warning, although that is there for a reason too. That one is just a warning though, right?

@ndom91
Copy link
Author

ndom91 commented Nov 13, 2025

I fixed all the remaining eslint issues (including the each keys) in that last commit. But give it a test please. I'm not sure where they're all used.

Hopefully there's not much more remaining 😅. Appreciate you working with me on this!

@MultiMote
Copy link
Owner

MultiMote commented Nov 14, 2025

image

Ofc feel free to add the ignore of the button label warning, although that is there for a reason too. That one is just a warning though, right?

With so many warnings, it's easy to miss something important.

let printState: "idle" | "sending" | "printing" = $state("idle");
let modal: Modal;
let printProgress: number = 0; // todo: more progress data
let density: number = $printerMeta?.densityDefault ?? 3;
Copy link
Owner

@MultiMote MultiMote Nov 14, 2025

Choose a reason for hiding this comment

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

Seems lile some state fields not converted to new state syntax (density/quantity/postProcessType and other).

@MultiMote MultiMote added the enhancement New feature or request label Nov 14, 2025
@ndom91
Copy link
Author

ndom91 commented Nov 14, 2025

Interesting, i used their auto migrate tool which i would have hoped caught all of the $state and onclick ones, those are relatively simple to auto migrate I'd imagine.

But no worries, I'll go back and get those 👌

@MultiMote
Copy link
Owner

MultiMote commented Nov 14, 2025

It was broken on upstream merge commit (6b7d48e).

@ndom91
Copy link
Author

ndom91 commented Nov 14, 2025

Fixed the on:clicks and it builds again now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants