@@ -7,13 +7,19 @@ const {
77} = require ( "electron" ) ;
88const path = require ( "path" ) ;
99const fs = require ( "fs/promises" ) ;
10+ const fsSync = require ( "fs" ) ; // Use sync version for setup
1011const { exec } = require ( "child_process" ) ;
1112const os = require ( "os" ) ;
13+ const sharp = require ( "sharp" ) ; // Import the sharp library
1214
13- // Make mainWindow a global variable so we can access it everywhere.
1415let mainWindow = null ;
1516
16- // Promisified exec for running osascript commands
17+ // --- App Setup: Create Thumbnail Cache Directory ---
18+ const cacheDir = path . join ( app . getPath ( "userData" ) , "thumbnails" ) ;
19+ if ( ! fsSync . existsSync ( cacheDir ) ) {
20+ fsSync . mkdirSync ( cacheDir , { recursive : true } ) ;
21+ }
22+
1723const run = ( cmd ) =>
1824 new Promise ( ( resolve , reject ) => {
1925 exec ( cmd , { maxBuffer : 1024 * 1024 * 10 } , ( error , stdout , stderr ) => {
@@ -23,14 +29,12 @@ const run = (cmd) =>
2329 } ) ;
2430 } ) ;
2531
26- // A dedicated function to set the wallpaper using AppleScript
2732async function setWallpaper ( imagePath ) {
2833 const script = `osascript -e 'tell application "System Events" to tell every desktop to set picture to (POSIX file "${ imagePath } ")'` ;
2934 return run ( script ) ;
3035}
3136
3237function createWindow ( ) {
33- // **FIX:** Get the display that currently has focus.
3438 const currentDisplay = screen . getDisplayNearestPoint (
3539 screen . getCursorScreenPoint ( )
3640 ) ;
@@ -42,7 +46,6 @@ function createWindow() {
4246 mainWindow = new BrowserWindow ( {
4347 width : windowWidth ,
4448 height : windowHeight ,
45- // Center the window on the currently active screen
4649 x : Math . round ( currentDisplay . bounds . x + ( width - windowWidth ) / 2 ) ,
4750 y : Math . round ( currentDisplay . bounds . y + ( height - windowHeight ) / 2 ) ,
4851 webPreferences : {
@@ -52,8 +55,8 @@ function createWindow() {
5255 } ,
5356 frame : false ,
5457 transparent : true ,
55- show : false , // Start hidden and show when ready
56- vibrancy : "ultra-dark" , // This provides the blurred transparency
58+ show : false ,
59+ vibrancy : "ultra-dark" ,
5760 alwaysOnTop : true ,
5861 level : "floating" ,
5962 visibleOnAllWorkspaces : true ,
@@ -67,22 +70,17 @@ function createWindow() {
6770
6871 mainWindow . loadFile ( path . join ( __dirname , "dist/index.html" ) ) ;
6972
70- // Show the window gracefully when the content is ready.
7173 mainWindow . once ( "ready-to-show" , ( ) => {
7274 mainWindow . show ( ) ;
7375 } ) ;
7476
75- // When the window is closed, set its variable to null.
76- // This is crucial for our open/close logic.
7777 mainWindow . on ( "closed" , ( ) => {
7878 mainWindow = null ;
7979 } ) ;
8080}
8181
8282app . whenReady ( ) . then ( ( ) => {
83- // Set up the global shortcut to toggle the window's visibility.
8483 globalShortcut . register ( "CommandOrControl+Shift+P" , ( ) => {
85- // If the window exists, close it. Otherwise, create it.
8684 if ( mainWindow ) {
8785 mainWindow . close ( ) ;
8886 } else {
@@ -91,11 +89,7 @@ app.whenReady().then(() => {
9189 } ) ;
9290} ) ;
9391
94- // **FIX:** Prevent the app from quitting when all windows are closed.
95- // This allows the background process to persist.
9692app . on ( "window-all-closed" , ( ) => {
97- // On macOS, it's common for applications to stay active until the user
98- // explicitly quits. This line prevents the default quit behavior.
9993 if ( process . platform !== "darwin" ) {
10094 app . quit ( ) ;
10195 }
@@ -114,9 +108,7 @@ ipcMain.handle("get-wallpapers", async () => {
114108 return files . filter ( ( file ) => / \. ( j p g | j p e g | p n g | h e i c | w e b p ) $ / i. test ( file ) ) ;
115109 } catch ( error ) {
116110 console . error ( `Error reading wallpaper directory: ${ wallpaperDir } ` , error ) ;
117- throw new Error (
118- `Could not read wallpapers from: ~/wallpapers. Please make sure this folder exists and isn't empty.`
119- ) ;
111+ throw new Error ( `Could not read wallpapers from: ~/wallpapers.` ) ;
120112 }
121113} ) ;
122114
@@ -142,24 +134,47 @@ ipcMain.handle("get-current-wallpaper", async () => {
142134 }
143135} ) ;
144136
145- ipcMain . handle ( "get-image-as-base64" , async ( event , fileIdentifier ) => {
146- let filePath ;
147- if ( path . isAbsolute ( fileIdentifier ) ) {
148- filePath = fileIdentifier ;
149- } else {
150- filePath = path . join ( os . homedir ( ) , "wallpapers" , fileIdentifier ) ;
151- }
152-
137+ // This handler is now only for the full-resolution initial background
138+ ipcMain . handle ( "get-image-as-base64" , async ( event , fullPath ) => {
153139 try {
154- const data = await fs . readFile ( filePath ) ;
140+ const data = await fs . readFile ( fullPath ) ;
155141 return data . toString ( "base64" ) ;
156142 } catch ( error ) {
157- console . error ( `Failed to read file: ${ filePath } ` , error ) ;
143+ console . error ( `Failed to read file: ${ fullPath } ` , error ) ;
158144 throw error ;
159145 }
160146} ) ;
161147
162- // This handler now closes the window instead of just hiding it.
148+ // **NEW**: Handler to get a cached thumbnail, creating it if it doesn't exist.
149+ ipcMain . handle ( "get-thumbnail" , async ( event , imageName ) => {
150+ const sourcePath = path . join ( os . homedir ( ) , "wallpapers" , imageName ) ;
151+ const thumbPath = path . join ( cacheDir , imageName ) ;
152+
153+ try {
154+ // Try to read from cache first
155+ await fs . access ( thumbPath ) ;
156+ const data = await fs . readFile ( thumbPath ) ;
157+ return data . toString ( "base64" ) ;
158+ } catch {
159+ // If cache miss, generate a new thumbnail
160+ try {
161+ const buffer = await sharp ( sourcePath )
162+ . resize ( { width : 400 } ) // Resize to 400px wide, maintaining aspect ratio
163+ . toBuffer ( ) ;
164+
165+ // Save the new thumbnail to the cache for next time
166+ await fs . writeFile ( thumbPath , buffer ) ;
167+ return buffer . toString ( "base64" ) ;
168+ } catch ( generationError ) {
169+ console . error (
170+ `Failed to generate thumbnail for ${ imageName } :` ,
171+ generationError
172+ ) ;
173+ throw generationError ;
174+ }
175+ }
176+ } ) ;
177+
163178ipcMain . on ( "hide-window" , ( ) => {
164179 if ( mainWindow ) {
165180 mainWindow . close ( ) ;
0 commit comments