Activity

Lorenzo U

Like any well-respected programmer, I too have a Spotify playlist on loop while I code, but lately, there are times when I just play a single song on repeat. I was about to start coding a section on the Google APIs, but I realized that Shard without Spotify just wouldn’t be Shard. So, I added it… initially, I left a single extra curly brace at the end of 600 lines of code. I save, reload the extension, and… pitch black. The dashboard had become a black abyss. The JavaScript engine had brutally crashed all because of a single, invisible character. I threw away a lot of time just dissecting the file, isolating the problem, and resurrecting the interface. Once the DOM was revived, I finally created the widget, but the iframe spat a laconic “Page not available” right in my face. Domain hiccup resolved, I thought I had won, but I still had to face the final boss: user links. While testing, I realized that nobody ever copies a clean link. If I pasted desktop URIs, everything broke. If I copied from the web, dragging along kilometer-long tracking parameters (?si=XYZ) or localized paths (/intl-it/), the iframe would explode. I tried patching the holes with replace(), but the code was turning into an unreadable monster.
So I deleted everything and forged the ultimate weapon: formatSpotifyEmbedUrl. No more cheap tricks, just a ruthless meat grinder. If there are trackers, it mows them down instantly with a brutal .split(“?”)[0], and then the black magic comes into play. I had to dust off Regular Expressions to create a formula capable of scanning the dirty string and surgically extracting only the media type and the unique ID, ignoring all the noise. Once these two pure pieces of data are extracted, I inject them into the one perfect URL that Spotify accepts. I lost half a day on it, but now you can paste the worst garbage link possible into the widget, and SHARD OS will unfailingly return an elegant player. It was worth it. 🚀 (I’ve really grown attached to this emoji :)

Attachment
Attachment
0
Lorenzo U

Today I realized a native To-Do list. I needed it.
I didn’t want the colorful, Post-it style of the Notes widget this time. I wanted this to feel deeply integrated into the system. So, I stripped away the solid colors and went all-in on the Glassmorphism theme. I built two variants:
Standard: A clean list with a dynamic counter at the top (e.g., “Active: 3 | 2/5 ✔️”).
Detailed: This is where I had fun. I added a sleek progress bar that fills up as you check off tasks, plus a timestamp for exactly when each task was added.
Everything was going great until I decided to give the user too much power.I wanted global settings to let users hide the “✕” (delete) button and the date text to keep the UI as minimal as possible. I wired up the HTML select menus, tied them to localStorage, and refreshed the page.
Boom. The entire dashboard exploded. 💥
The design broke, the settings menu refused to load, and half the widgets froze. I stared at the screen wondering how two simple boolean flags could cause a total system failure.
After hunting through the code, I found the culprit: a fatal ReferenceError inside populateSettings(). I had written settings.todoShowDelete instead of s.todoShowDelete. One wrong variable prefix, and the JavaScript engine just threw its hands up and quit reading the rest of the file. I fixed the prefix, cleaned up a couple of stray } braces, and the UI instantly snapped back to life.
I also had to make sure the JS didn’t crash trying to add click events to delete buttons that no longer existed in the DOM (thankfully, querySelectorAll().forEach is a lifesaver and just quietly ignores empty lists).
Now I have a fully functional, highly configurable, glass themed task manager right on my desktop. SHARD OS isn’t just a dashboard anymore; it’s becoming a real productivity beast! 🚀

Attachment
Attachment
Attachment
0
Lorenzo U

SHARD OS is great for fetching live data, but I realized I had nowhere to just jot down a quick thought. It was time to build the Notes widget!
I started simple: adding a new option to the + menu and rendering a standard . I wanted different variants that would override the default global glass theme. Everything went smoothly until testing, when I realized I had accidentally swapped the hex codes for Blue and Green. A classic developer moment: clicking “Blue” and getting a mint green window 😂
But a plain textarea felt too basic. I wanted formatting. I scrapped the textarea and unlocked the magic of . Boom. Instantly, Ctrl+B (Bold), Ctrl+I (Italic), and Ctrl+U (Underline) worked natively. A full Rich Text Editor in a single line of HTML!
First, the window title. Instead of a boring, static “NOTE”, I wrote a JS function that reads the innerHTML, splits it by line breaks, grabs the very first line, truncates it at 18 characters, and injects it into the top bar. It updates live, keystroke by keystroke!
Second, the drag conflict.Whenever I tried to highlight text with my mouse, the entire window would drag across the dashboard! I had to trap the mousedown event using e.stopPropagation() so that unless you are in global “Edit Mode”, the window stays glued to the desktop while you select text.
Finally, I focused on customization. I refactored the old “Meteo Config” sidebar into a broader “Widget Config” section, adding dropdowns for Font Families (like Courier for that typewriter feel) and Text Sizes. I noticed that applying these changes required a manual page refresh, which felt incredibly clunky. To fix this, I wired up a shiny “Apply & Reload” button that saves to localStorage and triggers a window.location.reload()
Oh, and I explicitly forced text-align: left because centered notes were driving my eyes crazy.
Now I have fully functional, format-ready, colorful sticky notes on my futuristic desktop.🚀

Attachment
Attachment
Attachment
Attachment
0
Lorenzo U

Details make the difference. Until yesterday, Clock and Weather were hardcoded to “Rome”. But what if I go on vacation? I added Location logic in the settings.
Manual: You write “New York”, I save the string, and call the weather API for that city.
Automatic: I used navigator.geolocation.getCurrentPosition(). The browser asks, “Shard wants to know your location.” If you say yes, I get the latitude and longitude and update the widgets. I had to handle denied permissions (if the user says NO, I revert to Rome as default so it doesn’t crash).

Attachment
Attachment
Attachment
0
Lorenzo U

Seeing the dashboard windows misaligned by 3 pixels was literally eating me alive. What should have been a trivial fix turned into 2 hours of obsessive testing to calibrate the Grid Snapping.

No heavy HTML grids to render, just pure, ruthless math injected into the mouseup event: finalX = Math.round(currentX / 20) * 20.

I force the coordinates to surgically snap to multiples of 20. When you release a window, it does a micro-snap and aligns to the millimeter with the others. The satisfaction is so visceral that I spent 20 minutes just dragging divs around the screen to enjoy that visual “click”.

Then, the cold sweat: “Wait… what if I accidentally clear Chrome’s cache? Do I lose the entire Shard OS setup?”

Panic kept me glued to the keyboard for the next 3 hours. Managing file I/O from an extension requires patience, and I had to write a proper save system:

Export (The Save): I grab the entire localStorage, crunch it through JSON.stringify(), and assemble a Blob in memory. From there, I generate a dynamic link that spits out a file with a proprietary .shard extension. Wrestling with the APIs to make the download trigger on the first try wasn’t trivial.

Import (The Restore): A reader that takes the .shard file, parses the JSON, and overwrites the variables on the fly, without crashing the widgets or the UI.

Reset (The Red Button): The dreaded localStorage.clear(). I locked it down behind a desperate confirm() (“Are you really, really sure??”). One misclick there and say goodbye to hours of configuration.

Today flew by, but now the infrastructure is rock solid and my windows are, finally, mathematically aligned.

Attachment
Attachment
0
Lorenzo U

I was sick of looking at the default space background. I worked on the Backgrounds system. I used the HTML and the FileReader API to read user-uploaded images, convert them to Base64 strings, and save them (hoping they aren’t too heavy for localStorage).
Then I worked on the “Layer” effects: How do windows behave on top of the background?
Liquid Glass: I abused backdrop-filter: blur(15px) saturate(180%). The effect is Apple Vision Pro style. Maybe heavy for some laptop GPUs, but beautiful.
Solid: Opaque white background for those who want to read clearly.
Dark: Semi-transparent black.
Now it looks like real premium software worth $99 (Why doesn’t clean, round $100 software exist? 😭).

Attachment
Attachment
Attachment
Attachment
Attachment
Attachment
Attachment
0
Lorenzo U

The home screen was turning into a chaotic marketplace with buttons everywhere. I spent a good chunk of these hours doing some heavy UI refactoring to clean things up, alongside building two new widgets.

The “+” Menu (The DOM Trap): I grouped “New Shard”, “Widget”, and “Web Page” into a custom dropdown. As any frontend dev knows, custom menus are a time sink. Handling event bubbling, perfecting the “click outside to close” (blur) logic, and polishing the CSS transitions took quite a bit of tweaking to get exactly right.

Search Widget (Pixel-Perfecting): A browser needs a search bar. Under the hood, it’s a simple form using window.open, but I lost time on the details: building dynamic engine switching (Google/Bing/DDG), hunting down and cleaning official SVGs for crisp 4K rendering, and managing state for threedifferent layouts.

Battery API & SVG Math: I tapped into Chrome’s navigator.getBattery(), which gives a simple promise with level and charging. The real effort went into my trademark 3-style layout. I built a classic filling icon, a custom Cyberpunk horizontal bar, and a percentage circle—which required wrestling with SVG math and stroke-dasharray to get the progress arc perfectly aligned.

Everything is now neatly packed into the “+” menu. The UI finally breathes, and the codebase feels much more scalable!

Attachment
Attachment
Attachment
Attachment
Attachment
Attachment
Attachment
Attachment
0
Lorenzo U

Today was a suuuper intense session. The goal was simply to render entire web pages inside my Shard windows using a basic .

Testing it out, I crashed into the wall of Security Headers. Sites like Google or OneDrive prevent embedding by setting the X-Frame-Options: DENY header and strict Content-Security-Policy. The initial result? The window loaded a depressing “Connection refused” icon.

The Solution? Declarative Net Request
Being in a Chrome extension environment (Manifest V3), I leveraged the network APIs. I created a rules.json tied to declarativeNetRequest to intercept the traffic.

The rule is surgical: for every resource of type sub_frame, the extension strips (removes) the x-frame-options and content-securitypolicy headers on the fly before the browser can even trigger them. Boom. The block is bypassed and it now works with almost all sites.

Once rendering was unlocked, the interface nightmare began:
Scrolling: The parent window absolutely could not scroll to avoid creating conflicts. I solved this by locking down the portal container with overflow: hidden and leaving the iframe completely free at width: 100%; height: 100%;.
and Dragging: Dragging a window that contains an iframe is a bloodbath because the iframe “swallows” the mouse events and blocks the drag. I fixed this by injecting an invisible .iframe-overlay over the web page: it activates (blocking clicks on the iframe) only when I trigger a mousedown on the title bar, and then instantly disappears on mouseup.

I struggled a lot with this, but having any site or dashboard always operational and persistent on the desktop is a killer feature. Totally worth it.

Attachment
0
Lorenzo U

Having different styles for the clock was cool… so the weather widget couldn’t be any less. I connected the Open-Meteo API (free and no key required, fantastic). The challenge was parsing the JSON.
I created 3 visualizations (different template literals):
Minimal: Just “12°C” in small text.
Icon: A giant SVG icon (Sun/Cloud) that changes based on the API’s wmo_code.
Detailed: Humidity, wind, and “feels like” temperature.
I wasted a lot of time vertically centering the icon and text (damn Flexbox), but now they are perfectly aligned with the clock.

Attachment
0
Lorenzo U

Using Shard heavily for testing, I realized there was a huge UX flaw. Often, I just wanted to read a note or check the time, but by clicking accidentally, I would move the window or resize it. The controls (the “X” to close, the resize handles) were visually annoying.
So, I decided to create Edit Mode.
I introduced a global flag: isEditMode = false.
I added a .read-only class to the body when editing is disabled.
Edit ON: You see dashed borders, window titles, close buttons.
Edit OFF: Everything is clean, minimal, windows are locked (pointer-events: none on controls).
Since I didn’t feel like creating new things, I improved existing ones: I built the ability to display a title for the shards. actually, I had already put in something similar, but I updated and fixed it further. I also added a ‘Settings’ button where you can choose the background color, element colors (created yesterday), and whether to show the shard title or not. Now the design breathes.

Attachment
Attachment
Attachment
0
Lorenzo U

I was thinking: “I need the time. I’ll just use the Google clock with the logic I created a few days ago—5 minutes and it’s done.”

Spoiler: Modern browsers “freeze background tabs. My clock would lag by 10 minutes every time I switched tabs. A disaster.

I scrapped everything and wrote updateSingleWidget in JS. I built the logic to make it work, and then I created three versions because customization is what makes SHARD unique!

  1. Classic
    I had to use .padStart(2, ‘0’). Why? Because seeing the time as 9:5 instead of 09:05 really got on my nerves. Now it’s perfect.

  2. Analog
    Here, I brushed up on my math with some web searches. The challenge was the hour hand. If you only use the hours, the hand snaps suddenly. The solution: (hours % 12) * 30 + minutes * 0.5. That + minutes * 0.5 is the magic that makes the hand glide smoothly as the minutes pass.

  3. Matrix Mode
    I wanted to show off, but the Matrix-style “code rain” was too heavy. I decided on something else: Unix Timestamp. Date.now().toString().slice(-10) I display time as the number of seconds passed since January 1, 1970 (the date computers started keeping time). No hours or minutes, just the inexorable flow of data: The nerds are going to love this. :)

Finally, I started adding different timezones, but for now, I’m putting that aside to focus on things I think are more important for SHARD.

I want the user to pick a color (e.g., Cyan) and have EVERYTHING turn Cyan: borders, text, icons, the clock. I had to rewrite my entire style.css file, replacing fixed colors with CSS Variables. I also added a Light/Dark mode switch.

And finally, I created a JS ThemeManager object that saves preferences in localStorage. I’d say SHARD is growing up fast, and so am I as I code it! See you tomorrow!

Attachment
Attachment
Attachment
Attachment
0
Lorenzo U

Static windows used to make me sad: they looked like stickers stuck to the screen. Today I implemented the resizing system!

For the user, it’s the most trivial thing in the world: you see a handle in the corner, drag it, and the window expands. Easy, right? NO. Anyone who’s ever tried to program an interface knows that behind that simple gesture is a bloodbath of math. 🩸

I had to orchestrate a dance between mouse events:

mousedown: Got it. (activate the isResizing flag)

mousemove: Real-time X and Y coordinate calculations.

mouseup: Hold still! (save the new size)

At first, it was tragic. If I dragged the mouse too quickly to the left, the window width would go negative (width < -50px). Result? The DIV would “flip” and disappear into nothingness. I spent 20 minutes searching for ghost windows in the DOM.

Luckily, I had a lightbulb moment 💡 (I remembered an old project where I solved something similar). I added a “safety block” both in the CSS and JS:

if (newWidth > 50) { element.style.width = newWidth + ‘px’ }

Basically, I’m telling the code, “Hey, if it gets smaller than a stamp, stop!” I also had to wrestle with getBoundingClientRect() to calculate the absolute position relative to the parent, but in the end, after several attempts, I did it!

Now it’s super smooth. I can create a setup with giant cinema windows or tiny sticky notes. Shard is slowly taking shape and is starting to look like a real OS! 🚀

P.S. This is already the second Dev Log I’ve ended with the spaceship emoji, I think NASA might actually hire me 🙃

Attachment
0
Lorenzo U

Here’s how the Shard capture system was born.
The idea was simple: Ctrl + Click on anything = one Shard on the dashboard, a data point that updates live (number, price, etc.). But building it? A nightmare.
I started by fighting with manifest.json. Chrome doesn’t let you improvise, so I had to enable activeTab and scripting. Without them, the extension is useless.
Then I added an “ear” to the browser with document.addEventListener(‘click’).
No CTRL? Nothing happens.
CTRL pressed? The trap snaps shut.
The tricky part was surgery. At first I used e.target to detect what I clicked, but it was a disaster. On Amazon I’d grab half the page reviews, footer, everything.
So I rewrote it using document.elementFromPoint(x, y). An invisible laser aimed at the mouse coordinates, giving me exactly the element under the cursor (price, title, image). Pure magic.
I was hyped… until I opened a New Tab: black screen. Panic.
I’d saved the data locally, but forgot to write the function that reads it on startup. SHARD tried to draw windows that didn’t exist and crashed the renderer. After fixing the crash, the data was still dead.
Then came the battle of “Live” ⚡.
At first I reloaded the page, but SHARD always showed old data.The problem? Chrome was using the cache. I tried everything until the solution clicked: add a random number to every request (url?t=12345). Chrome thinks it’s a new page and fetches fresh data. Now it reloads every 5 seconds.
In the end, I was happy but Google wasn’t.
I tried cloning the page style (cloneNode) to keep fonts and layout, but on Google/Facebook? White screen. That’s Content Security Policy: the giants don’t like being cloned
Conclusion: I built a desktop that steals data in real time and tricks the cache.
Does it have limits? Yes.
Is it the coolest thing I’ve ever written? Absolutely.
Now it looks like a space control station. 🚀

Attachment
Attachment
0
Lorenzo U

Today I wanted to create my first “window”. I wanted that futuristic, frosted glass look (kind of like Windows 11 and Apple’s Liquid Glass. The technical name is Glassmorphism). I wrote my own CSS. At first I used opacity: 0.5. Result: horrible. You could see through it, but the text also became transparent and unreadable! After 45 minutes of research I discovered the magic property: backdrop-filter: blur(15px). I added a space background to the body and… WOW. The div looked like a piece of real glass that blurred the stars behind it. I struggled with the borders. border: 1px solid white was too strong. I learned how to use rgba to make a semi-transparent border. Now I have a beautiful rectangle in the center of the screen. It doesn’t do anything, it doesn’t move, but it’s beautiful :)

Attachment
0
Lorenzo U

The Spark 💡

Hello world! Today I think something big was born. I was looking at Google’s start page — so static and boring — and I thought: “Why can’t I have an OS inside the browser?” 🤔
I grabbed a pen and started brainstorming. I don’t want a simple “New Tab” page; I want a space-like, highly customizable interface. I’ll call it Shard OS.
The idea is to have floating web “fragments” (shards). Let’s get started! ☕️

I began by building the Architecture and File System 📂.
First of all, I can’t just make a website — I want something that actually replaces that boring page. I’ve got it: a Chrome extension!

I decided on the file structure. I’ll definitely need 6 core files (maybe more in the future):

manifest.json (The app’s passport)

dashboard.html (The desktop)

dashboard.css (The style — and there will be a lot of it)

dashboard.js (The brain)

background.js (To save parts of websites — probably unnecessary, but we’ll see)

An icons folder (because aesthetics matter)

It doesn’t look like much, but order is half the work (I don’t know who said that… maybe someone famous. Oh wait, it was my mom telling me to clean my room)! 🤓

I started coding the manifest — the cursed Manifest 📜.
It looks easy, but Chrome is really picky about permissions. I had to define chrome_url_overrides to replace the “New Tab” page.

First bug: I forgot a comma in the JSON and the extension wouldn’t load. I spent 20 minutes staring at the screen before noticing it. Luckily, rubber duck debugging came to the rescue! 😂
Now it loads a blank page when I open a new tab — the most beautiful blank page I’ve ever seen.

I also sketched some early design ideas and came up with an acronym for SHARD (otherwise everyone would think of The Shard in London):
Smart Hybrid Access & Resource Dashboard

I went on a bit too long with this devlog today. See you tomorrow, when we’ll start the real programming! 🚀

Attachment
0