diff --git a/kittens/choose_files/graphics.go b/kittens/choose_files/graphics.go index e6b675a5e..4ce09af1f 100644 --- a/kittens/choose_files/graphics.go +++ b/kittens/choose_files/graphics.go @@ -283,14 +283,14 @@ func (self *GraphicsHandler) RenderImagePreview(h *Handler, p *ImagePreview, x, } files_supported := self.files_supported.Load() - if p.img_metadata.Width <= px_width && p.img_metadata.Height <= px_height { + if p.custom_metadata.image.Width <= px_width && p.custom_metadata.image.Height <= px_height { if files_supported { - self.transmit(h.lp, nil, p.img_metadata, p.cached_data) + self.transmit(h.lp, nil, p.custom_metadata.image, p.cached_data) } else { if err = p.ensure_source_image(); err != nil { return } - self.transmit(h.lp, p.source_img, p.img_metadata, nil) + self.transmit(h.lp, p.source_img, p.custom_metadata.image, nil) } return } diff --git a/kittens/choose_files/image_preview.go b/kittens/choose_files/image_preview.go index 9b96be5a2..d538499ba 100644 --- a/kittens/choose_files/image_preview.go +++ b/kittens/choose_files/image_preview.go @@ -35,19 +35,25 @@ type ShowData struct { metadata fs.FileInfo x, y, width, height int cached_data map[string]string - img_metadata *images.SerializableImageMetadata + custom_metadata metadata } type PreviewRenderer interface { - Render(string) (map[string][]byte, *images.ImageData, error) + Unmarshall(map[string]string) (any, error) + Render(string) (map[string][]byte, metadata, *images.ImageData, error) ShowMetadata(h *Handler, s ShowData) int } type render_data struct { - cached_data map[string]string - img *images.ImageData - img_metadata *images.SerializableImageMetadata - err error + cached_data map[string]string + img *images.ImageData + metadata metadata + err error +} + +type metadata struct { + image *images.SerializableImageMetadata + custom any } type ImagePreview struct { @@ -59,7 +65,7 @@ type ImagePreview struct { render_channel chan render_data ready atomic.Bool source_img *images.ImageData - img_metadata *images.SerializableImageMetadata + custom_metadata metadata renderer PreviewRenderer file_metadata_preview Preview WakeupMainThread func() bool @@ -124,7 +130,7 @@ func (p *ImagePreview) render_image(h *Handler, x, y, width, height int) { offset := p.renderer.ShowMetadata(h, ShowData{ abspath: p.abspath, metadata: p.metadata, x: x, y: y, width: width, height: height, cached_data: p.cached_data, - img_metadata: p.img_metadata, + custom_metadata: p.custom_metadata, }) h.graphics_handler.RenderImagePreview(h, p, x, y+offset, width, height-offset) } @@ -143,7 +149,7 @@ func (p *ImagePreview) Render(h *Handler, x, y, width, height int) { p.render_channel = nil p.cached_data = hd.cached_data p.source_img = hd.img - p.img_metadata = hd.img_metadata + p.custom_metadata = hd.metadata if hd.err != nil { p.render_err = NewErrorPreview(fmt.Errorf("Failed to render the preview with error: %w", hd.err)) } @@ -178,20 +184,21 @@ func (p *ImagePreview) start_rendering() { if b, err := os.ReadFile(d); err == nil { var m images.SerializableImageMetadata if err = json.Unmarshal(b, &m); err == nil { - p.render_channel <- render_data{cached_data: ans, img_metadata: &m} - return + if cm, err := p.renderer.Unmarshall(ans); err == nil { + p.render_channel <- render_data{cached_data: ans, metadata: metadata{image: &m, custom: cm}} + return + } } } } } - rdata, img, err := p.renderer.Render(p.abspath) + rdata, metadata, img, err := p.renderer.Render(p.abspath) if err != nil { p.render_channel <- render_data{err: err} } else { ans, err = p.disk_cache.AddPath(p.abspath, key, rdata) if err == nil { - m := img.SerializeOnlyMetadata() - p.render_channel <- render_data{cached_data: ans, img_metadata: &m, img: img} + p.render_channel <- render_data{cached_data: ans, metadata: metadata, img: img} } else { p.render_channel <- render_data{err: err} } @@ -200,17 +207,18 @@ func (p *ImagePreview) start_rendering() { type ImagePreviewRenderer uint -func (p ImagePreviewRenderer) Render(abspath string) (ans map[string][]byte, img *images.ImageData, err error) { +func (p ImagePreviewRenderer) Render(abspath string) (ans map[string][]byte, m metadata, img *images.ImageData, err error) { if img, err = images.OpenImageFromPath(abspath); err != nil { - return nil, nil, err + return nil, metadata{}, nil, err } - m, data := img.Serialize() + im, data := img.Serialize() ans = make(map[string][]byte, len(data)+1) - metadata, err := json.Marshal(m) + sm, err := json.Marshal(im) if err != nil { - return nil, nil, err + return nil, metadata{}, nil, err } - ans[IMAGE_METADATA_KEY] = metadata + ans[IMAGE_METADATA_KEY] = sm + m = metadata{image: &im} for i, d := range data { key := IMAGE_DATA_PREFIX + strconv.Itoa(i) ans[key] = d @@ -218,11 +226,13 @@ func (p ImagePreviewRenderer) Render(abspath string) (ans map[string][]byte, img return } +func (p ImagePreviewRenderer) Unmarshall(map[string]string) (any, error) { return nil, nil } + func (p ImagePreviewRenderer) ShowMetadata(h *Handler, s ShowData) int { text := "" offset := 0 - if s.img_metadata != nil { - text = fmt.Sprintf("%s: %dx%d %s", s.img_metadata.Format_uppercase, s.img_metadata.Width, s.img_metadata.Height, humanize.Bytes(uint64(s.metadata.Size()))) + if m := s.custom_metadata.image; m != nil { + text = fmt.Sprintf("%s: %dx%d %s", m.Format_uppercase, m.Width, m.Height, humanize.Bytes(uint64(s.metadata.Size()))) icon := icons.IconForPath("/a.gif") text = icon + " " + text offset += h.render_wrapped_text_in_region(text, s.x, s.y, s.width, s.height, true)