Skip to content

Commit 210f23b

Browse files
committed
Phase 2.5: Icon freshness
- Create test file generator functionality to generate file types and check icons, incl. 4 colored circle `.icns` files for custom folder icons - Add `config.rs` for constants - Add `get_icons_for_paths` for per-path directory icons - Parallelize icon fetching with rayon - Add `refresh_directory_icons` - Add Tauri command - Update frontend to refresh icons on directory load - Re-fetch extension icons on each load for freshness - Add `#![deny(unused)]` to enable dead code detection - Add benchmark with cargo bench + criterion → Turns out the default number of threads is best.
1 parent c024eaf commit 210f23b

19 files changed

Lines changed: 516 additions & 49 deletions

File tree

eslint.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import globals from 'globals'
2323

2424
export default tseslint.config(
2525
{
26-
ignores: ['dist', 'build', '.svelte-kit', 'node_modules', 'src-tauri/target'],
26+
ignores: ['dist', 'build', '.svelte-kit', 'node_modules', 'src-tauri/target', '_ignored'],
2727
},
2828
js.configs.recommended,
2929
prettierConfig,

knip.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"$schema": "https://unpkg.com/knip@5/schema.json",
3-
"ignore": [],
3+
"ignore": ["src/lib/icon-cache.ts"],
44
"ignoreDependencies": ["@tauri-apps/plugin-window-state", "@testing-library/svelte"],
55
"ignoreExportsUsedInFile": true
66
}
101 KB
Binary file not shown.
101 KB
Binary file not shown.
101 KB
Binary file not shown.
102 KB
Binary file not shown.

scripts/test-data-generator/main.go

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"fmt"
88
"math/rand"
99
"os"
10+
"os/exec"
1011
"path/filepath"
1112
"strings"
1213
"time"
@@ -203,10 +204,116 @@ func syncFolder(folderPath string, targetCount int) error {
203204
return nil
204205
}
205206

207+
// createIconTestData creates a folder with various file types for testing icons.
208+
// Includes: fake files with different extensions, symlinks, and folders with custom icons.
209+
func createIconTestData(baseDir string) error {
210+
iconDir := filepath.Join(baseDir, "icons")
211+
fmt.Printf("Creating icon test data in %s/\n", iconDir)
212+
213+
// Clean and recreate the folder
214+
if err := os.RemoveAll(iconDir); err != nil {
215+
return fmt.Errorf("failed to remove existing icon folder: %w", err)
216+
}
217+
if err := os.MkdirAll(iconDir, 0755); err != nil {
218+
return fmt.Errorf("failed to create icon folder: %w", err)
219+
}
220+
221+
// Create fake files with various extensions
222+
fakeFiles := []string{
223+
"fake-report.pdf",
224+
"fake-document.docx",
225+
"fake-spreadsheet.xlsx",
226+
"fake-notes.txt",
227+
"fake-script.ts",
228+
"fake-program.go",
229+
"fake-code.rs",
230+
"fake-config.json",
231+
"fake-data.csv",
232+
"fake-archive.zip",
233+
"fake-photo.jpg",
234+
"fake-image.png",
235+
"fake-video.mp4",
236+
"fake-audio.mp3",
237+
"fake-presentation.pptx",
238+
"fake-database.db",
239+
"fake-markup.html",
240+
"fake-styles.css",
241+
"fake-readme.md",
242+
"fake-shell.sh",
243+
}
244+
245+
fmt.Printf(" Creating %d fake files...\n", len(fakeFiles))
246+
for _, name := range fakeFiles {
247+
filePath := filepath.Join(iconDir, name)
248+
content := fmt.Sprintf("This is a fake %s file for icon testing.\n", filepath.Ext(name))
249+
if err := os.WriteFile(filePath, []byte(content), 0644); err != nil {
250+
return fmt.Errorf("failed to create %s: %w", name, err)
251+
}
252+
}
253+
254+
// Create a symlink
255+
fmt.Println(" Creating symlink...")
256+
symlinkPath := filepath.Join(iconDir, "symlink-to-fake-photo.jpg")
257+
if err := os.Symlink("fake-photo.jpg", symlinkPath); err != nil {
258+
return fmt.Errorf("failed to create symlink: %w", err)
259+
}
260+
261+
// Create folders with custom icons
262+
assetsDir := "scripts/test-data-generator/assets/icons"
263+
iconColors := []string{"red", "blue", "green", "yellow"}
264+
265+
fmt.Printf(" Creating %d folders with custom icons...\n", len(iconColors))
266+
for _, color := range iconColors {
267+
folderName := fmt.Sprintf("%s-folder", color)
268+
folderPath := filepath.Join(iconDir, folderName)
269+
270+
if err := os.MkdirAll(folderPath, 0755); err != nil {
271+
return fmt.Errorf("failed to create folder %s: %w", folderName, err)
272+
}
273+
274+
// Create a readme inside the folder
275+
readmePath := filepath.Join(folderPath, "README.md")
276+
readmeContent := fmt.Sprintf("# %s Folder\n\nThis folder has a custom %s circle icon.\n", strings.Title(color), color)
277+
if err := os.WriteFile(readmePath, []byte(readmeContent), 0644); err != nil {
278+
return fmt.Errorf("failed to create README in %s: %w", folderName, err)
279+
}
280+
281+
// Apply custom icon using fileicon CLI (macOS only)
282+
icnsPath := filepath.Join(assetsDir, fmt.Sprintf("%s-circle.icns", color))
283+
if _, err := os.Stat(icnsPath); err == nil {
284+
// fileicon is available via: brew install fileicon
285+
cmd := exec.Command("fileicon", "set", folderPath, icnsPath)
286+
if err := cmd.Run(); err != nil {
287+
fmt.Printf(" Warning: failed to set icon for %s (install fileicon: brew install fileicon)\n", folderName)
288+
}
289+
}
290+
}
291+
292+
// Create a regular folder (no custom icon)
293+
regularFolder := filepath.Join(iconDir, "regular-folder")
294+
if err := os.MkdirAll(regularFolder, 0755); err != nil {
295+
return fmt.Errorf("failed to create regular folder: %w", err)
296+
}
297+
if err := os.WriteFile(filepath.Join(regularFolder, "README.md"), []byte("# Regular Folder\n\nThis folder has the default macOS folder icon.\n"), 0644); err != nil {
298+
return fmt.Errorf("failed to create README in regular folder: %w", err)
299+
}
300+
301+
fmt.Println(" Icon test data created successfully!")
302+
return nil
303+
}
304+
206305
func main() {
207306
baseDir := "_ignored/test-data"
208307
fmt.Printf("Syncing test data folders in %s/\n\n", baseDir)
209308

309+
// Create icon test data first
310+
if err := createIconTestData(baseDir); err != nil {
311+
_, _ = fmt.Fprintf(os.Stderr, "Error creating icon test data: %v\n", err)
312+
os.Exit(1)
313+
}
314+
fmt.Println()
315+
316+
// Sync large file count folders
210317
for folderName, target := range targets {
211318
folderPath := filepath.Join(baseDir, folderName)
212319
if err := syncFolder(folderPath, target); err != nil {

0 commit comments

Comments
 (0)