Low-Fi Finder Image Grid View 🖼️

Low-Fi Finder Image Grid View 🖼️

While list views are nice, sometimes you just want a grid 😄. Here, I played around with displaying images in a grid layout.

I'd even say that grids feel like a natural extension to the layouts in #231 🤓

I started this project a little while back, and am currently using the html panel as opposed to choice.html. To support custom actions on selection (e.g. copy image filepath to clipboard on choice selection) within a grid context, I think that there is at least one missing piece.

Enable setting className / styles of choice button parent container

In my example, I'm doing a self-described css injection to add new styles (e.g. .grid-cols-3 {grid-template-columns: repeat(3, minmax(0, 1fr))}), but the styles probably could be done in-line.

Demo

image_grid

Code

lib/image-grid.js
// lib/image-grid.js
const DEFAULT_LIMIT = 10000; // 1000; // 100;
const DEBUG = { ENABLED: false };
const debug = (...args) => DEBUG.ENABLED && console.log(...args)
const info = (...args) => console.log(...args)
export const enableDebugMode = () => { DEBUG.ENABLED = true }
const getImages = (filepath, maxdepth) => {
// NOTE: options to use "-ctime -90d" / "-atime -90d" to filter more results
const findCommand = `find -E ${filepath} -iregex '.*\.(jpg|jpeg|png|gif)' -maxdepth ${maxdepth}`
const findSortedCommand = `${findCommand} -print0 | xargs -0 ls -at`
debug("findSortedCommand", findSortedCommand)
return exec(findSortedCommand, { silent: true }).toString().split("\n").filter(v => v)
}
const buildImageModal = (payload) => {
let {file} = payload;
const img = `<img src="${file}">`
return `<div class="imgContainer">${img}</div>`
}
const injectCss = (html) => {
// our tailwind build doesn't include grid css
// we add some custom styles as well
const css = `
/* Mimic tailwind grid css */
.grid {display:grid}
.grid-cols-3 {grid-template-columns: repeat(3, minmax(0, 1fr))}
.grid-cols-4 {grid-template-columns: repeat(4, minmax(0, 1fr))}
.grid-cols-5 {grid-template-columns: repeat(5, minmax(0, 1fr))}
/* custom css to center images in grid */
.grid div {place-items: center; padding: clamp(1px, 4%, 25px);}
.imgContainer {display: flex;}
`
const style = `<style type="text/css">${css}</style>`
return `${style}${html}`
}
const buildPage = (imageObjects, limit = DEFAULT_LIMIT) => {
const subset = imageObjects
.slice(0, limit)
.map(file => { return { file } })
const columns = subset.length > 32 ? (subset.length > 64 ? 5 : 4) : 3
const modals = subset.map(buildImageModal).join('\n')
const html = `<div class="grid grid-cols-${columns} pt-1 m-1">${modals}</div>`
const page = injectCss(html)
debug(page);
info('buildPage: Done')
return page
}
export const buildImagesPanel = async (filepath, maxdepth, limit) => {
const images = getImages(filepath, maxdepth);
info(`Found ${images.length} images`);
await arg({
input: " ",
}, buildPage(images, limit));
}
view-desktop.js
// Menu: View Desktop
// Description: View Desktop Attachments
// Author: Zach Zeleznick
// Twitter: @zzxiv
// Shortcut: cmd shift d
const {buildImagesPanel} = await lib("image-grid")
const filepath = "~/Desktop"
const depth = "3"
await buildImagesPanel(filepath, depth)
view-attachments.js
// Menu: View Attachment
// Description: View iMessage Attachments
// Author: Zach Zeleznick
// Twitter: @zzxiv
// Shortcut: cmd shift l
const {buildImagesPanel} = await lib("image-grid")
// NOTE: Need to grant Kit app full disk access in Security and Privacy or find will return 0 results
const filepath = "~/Library/Messages/Attachments"
const depth = "4"
await buildImagesPanel(filepath, depth)
view-downloads.js
// Menu: View Download
// Description: View Download Attachments
// Author: Zach Zeleznick
// Twitter: @zzxiv
// Shortcut: cmd shift 0
const {buildImagesPanel, enableDebugMode} = await lib("image-grid")
const filepath = "~/Downloads"
const depth = "2"
const limit = 42
enableDebugMode()
await buildImagesPanel(filepath, depth, limit)

Reference

Here are a few screenshots of the native Finder window on macOS 10.14 that I intended to recreate in low-fidelity.

Native ViewSorting Options
Example search for `png` files on my DesktopSorting options