fix(msgviewer): use pager for all text, replace image markers with readable placeholders
The composite renderer bypassed the pager (less) for any email with images, losing colors, scrolling, and search. Now always forward to the pager with [image: alt] text placeholders. Image refs are still extracted and stored for future inline rendering.
This commit is contained in:
+13
-17
@@ -634,16 +634,16 @@ func (pv *PartViewer) attemptCopy() {
|
|||||||
cleaned, images := parse.ExtractImages(&filterBuf)
|
cleaned, images := parse.ExtractImages(&filterBuf)
|
||||||
if len(images) > 0 {
|
if len(images) > 0 {
|
||||||
pv.imageRefs = images
|
pv.imageRefs = images
|
||||||
cleanedBytes, _ := io.ReadAll(cleaned)
|
log.Debugf("extracted %d image refs from filter output", len(images))
|
||||||
pv.composite = newCompositeContent(
|
}
|
||||||
string(cleanedBytes), images, 80)
|
// Always forward to pager — placeholders are readable text
|
||||||
pv.Invalidate()
|
// Image markers become \x00IMG:N\x00 which we replace
|
||||||
} else {
|
// with human-readable [image: alt] text for the pager.
|
||||||
// No images — forward to pager as normal
|
cleanedBytes, _ := io.ReadAll(cleaned)
|
||||||
_, copyErr := io.Copy(pv.pagerin, cleaned)
|
output := parse.ReplacePlaceholders(cleanedBytes, images)
|
||||||
if copyErr != nil {
|
_, copyErr := io.Copy(pv.pagerin, bytes.NewReader(output))
|
||||||
log.Errorf("io.Copy: %s", copyErr)
|
if copyErr != nil {
|
||||||
}
|
log.Errorf("io.Copy: %s", copyErr)
|
||||||
}
|
}
|
||||||
err = pv.pagerin.Close()
|
err = pv.pagerin.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -838,13 +838,9 @@ func (pv *PartViewer) Draw(ctx *ui.Context) {
|
|||||||
if pv.term != nil {
|
if pv.term != nil {
|
||||||
pv.term.Draw(ctx)
|
pv.term.Draw(ctx)
|
||||||
}
|
}
|
||||||
// Composite mode: text + images from filter output
|
// NOTE: Composite image rendering (pv.composite) is reserved for
|
||||||
if pv.composite != nil {
|
// future use. Currently all filter output goes through the pager
|
||||||
pv.composite.width = ctx.Width()
|
// with [image: alt] text placeholders for extracted images.
|
||||||
ctx.Fill(0, 0, ctx.Width(), ctx.Height(), ' ', pv.uiConfig.GetStyle(config.STYLE_DEFAULT))
|
|
||||||
pv.composite.Draw(ctx, pv.scroll)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if pv.image != nil && (pv.resized(ctx) || pv.graphic == nil) {
|
if pv.image != nil && (pv.resized(ctx) || pv.graphic == nil) {
|
||||||
// This path should only occur on resizes or the first pass
|
// This path should only occur on resizes or the first pass
|
||||||
// after the image is downloaded and could be slow due to
|
// after the image is downloaded and could be slow due to
|
||||||
|
|||||||
@@ -39,3 +39,33 @@ func ExtractImages(r io.Reader) (io.Reader, []ImageRef) {
|
|||||||
}
|
}
|
||||||
return buf, images
|
return buf, images
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReplacePlaceholders converts \x00IMG:N\x00 placeholders into human-readable
|
||||||
|
// [image: alt] text suitable for display in a pager.
|
||||||
|
func ReplacePlaceholders(data []byte, images []ImageRef) []byte {
|
||||||
|
result := bytes.NewBuffer(nil)
|
||||||
|
for _, line := range bytes.Split(data, []byte("\n")) {
|
||||||
|
trimmed := bytes.TrimSpace(line)
|
||||||
|
if len(trimmed) > 6 && trimmed[0] == 0 &&
|
||||||
|
bytes.HasPrefix(trimmed, []byte("\x00IMG:")) &&
|
||||||
|
trimmed[len(trimmed)-1] == 0 {
|
||||||
|
// Extract index
|
||||||
|
numStr := string(trimmed[5 : len(trimmed)-1])
|
||||||
|
idx := 0
|
||||||
|
for _, c := range numStr {
|
||||||
|
if c >= '0' && c <= '9' {
|
||||||
|
idx = idx*10 + int(c-'0')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if idx < len(images) && images[idx].Alt != "" {
|
||||||
|
fmt.Fprintf(result, "[image: %s]\n", images[idx].Alt)
|
||||||
|
} else {
|
||||||
|
result.WriteString("[image]\n")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result.Write(line)
|
||||||
|
result.WriteByte('\n')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.Bytes()
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user