all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* [bug#68680] [PATCH mumi 0/3] Add a button to copy a message Message-ID to the clipboard.
@ 2024-01-24  2:15 Maxim Cournoyer
  2024-01-24  2:20 ` [bug#68680] [PATCH mumi 1/3] README.org: Add new sections to help newcomers get started Maxim Cournoyer
                   ` (4 more replies)
  0 siblings, 5 replies; 28+ messages in thread
From: Maxim Cournoyer @ 2024-01-24  2:15 UTC (permalink / raw)
  To: 68680; +Cc: Maxim Cournoyer

This series adds a new HTML element to each message header to easily
copy the Message-ID of a message into the clipboard.  It makes use of
the (already included) Pico CSS library for tooltips and some new
JavaScript event handler.  The motivation was to make it easier to
retrieve the Message-ID for passing it to the 'b4 shazam' command when
applying long patches series.


Maxim Cournoyer (3):
  README.org: Add new sections to help newcomers get started.
  .gitignore: Register mumi.xapian and signing-key files.
  html: Add a button to copy a Message-ID to the clipboard.

 .gitignore              |  2 ++
 README.org              | 24 ++++++++++++++++++++++
 assets/js/mumi.js       | 31 ++++++++++++++++++++++++++++-
 assets/mumi.scss        | 23 ++++++++++++++++++---
 mumi/web/view/html.scm  | 20 +++++++++++++++----
 mumi/web/view/utils.scm | 44 +++++++++++++++++++++++++++--------------
 6 files changed, 121 insertions(+), 23 deletions(-)


base-commit: 025fc600f1cb4c73042bf920aee3e07d5fb9c53a
-- 
2.41.0





^ permalink raw reply	[flat|nested] 28+ messages in thread

* [bug#68680] [PATCH mumi 1/3] README.org: Add new sections to help newcomers get started.
  2024-01-24  2:15 [bug#68680] [PATCH mumi 0/3] Add a button to copy a message Message-ID to the clipboard Maxim Cournoyer
@ 2024-01-24  2:20 ` Maxim Cournoyer
  2024-01-24  2:20   ` [bug#68680] [PATCH mumi 2/3] .gitignore: Register mumi.xapian and signing-key files Maxim Cournoyer
  2024-01-24  2:20   ` [bug#68680] [PATCH mumi 3/3] html: Add a button to copy a Message-ID to the clipboard Maxim Cournoyer
  2024-01-24  2:29 ` [bug#68680] [PATCH mumi 0/3] Add a button to copy a message " Maxim Cournoyer
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 28+ messages in thread
From: Maxim Cournoyer @ 2024-01-24  2:20 UTC (permalink / raw)
  To: 68680; +Cc: Maxim Cournoyer

* README.org (Running a local instance of mumi): New section.
(Disabling browser caching): Likewise.
---

 README.org | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/README.org b/README.org
index fd1d77b..d092de7 100644
--- a/README.org
+++ b/README.org
@@ -11,3 +11,27 @@ run
 #+BEGIN_SRC shell
   $ guix shell -D mumi
 #+END_SRC
+
+** Running a local instance of mumi
+
+First copy some test mail data to be indexed:
+
+#+begin_src shell
+  $ cp -a tests/data data
+#+end_src
+
+Then, to have these emails indexed, run:
+
+#+begin_src shell
+  $ ./pre-inst-env mumi fetch
+#+end_src
+
+You should now be able to visit http://0.0.0.0:1234 in your browser
+and see your local mumi instance running.
+
+** Disabling browser caching
+
+If you modify the CSS or JavaScript source files, you'll want to make
+sure your browser doesn't keep cached copies.  This can be done by
+changing a preference in the development tools menus, which is called
+something like "Disable cache (while DevTools is active)".
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [bug#68680] [PATCH mumi 2/3] .gitignore: Register mumi.xapian and signing-key files.
  2024-01-24  2:20 ` [bug#68680] [PATCH mumi 1/3] README.org: Add new sections to help newcomers get started Maxim Cournoyer
@ 2024-01-24  2:20   ` Maxim Cournoyer
  2024-01-24  2:20   ` [bug#68680] [PATCH mumi 3/3] html: Add a button to copy a Message-ID to the clipboard Maxim Cournoyer
  1 sibling, 0 replies; 28+ messages in thread
From: Maxim Cournoyer @ 2024-01-24  2:20 UTC (permalink / raw)
  To: 68680; +Cc: Maxim Cournoyer

Signed-off-by: Maxim Cournoyer <maxim.cournoyer@gmail.com>
---

 .gitignore | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.gitignore b/.gitignore
index 2604e48..7247392 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,8 +8,10 @@ config.log
 config.status
 configure
 
+mumi.xapian
 mumi/config.scm
 scripts/mumi
+signing-key
 pre-inst-env
 *.log
 *.trs
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [bug#68680] [PATCH mumi 3/3] html: Add a button to copy a Message-ID to the clipboard.
  2024-01-24  2:20 ` [bug#68680] [PATCH mumi 1/3] README.org: Add new sections to help newcomers get started Maxim Cournoyer
  2024-01-24  2:20   ` [bug#68680] [PATCH mumi 2/3] .gitignore: Register mumi.xapian and signing-key files Maxim Cournoyer
@ 2024-01-24  2:20   ` Maxim Cournoyer
  1 sibling, 0 replies; 28+ messages in thread
From: Maxim Cournoyer @ 2024-01-24  2:20 UTC (permalink / raw)
  To: 68680; +Cc: Maxim Cournoyer

* mumi/web/view/html.scm (issue-page)
<copy-message-id-button>: New HTML element.
* mumi/web/view/utils.scm (download-icon): Update source.  Use 'rem'
as size unit.
(copy-icon): New variable.
(display-message-body) <download-part>: Add IDs to buttons.  Add to
"message-button" class.
* assets/mumi.scss: Refactor spacing of message header buttons via a
flex display.  Add a shrinking animation to message buttons on hover.
* assets/js/mumi.js (mumi): Register an event for it that copies the
Message-ID to the clipboard.  Add js-indent-level prop line.

Signed-off-by: Maxim Cournoyer <maxim.cournoyer@gmail.com>
---

 assets/js/mumi.js       | 31 ++++++++++++++++++++++++++++-
 assets/mumi.scss        | 23 ++++++++++++++++++---
 mumi/web/view/html.scm  | 20 +++++++++++++++----
 mumi/web/view/utils.scm | 44 +++++++++++++++++++++++++++--------------
 4 files changed, 95 insertions(+), 23 deletions(-)

diff --git a/assets/js/mumi.js b/assets/js/mumi.js
index ab29f08..0d25c5a 100644
--- a/assets/js/mumi.js
+++ b/assets/js/mumi.js
@@ -1,4 +1,4 @@
-// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3.0-or-later
+// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3.0-or-later  -*- js-indent-level: 2; -*-
 var mumi = (function () {
   const possibleTokens = [
     { text: 'is:open' },
@@ -129,12 +129,41 @@ var mumi = (function () {
   var init = function () {
     initTokenInput ();
   };
+
+  // Copy a message Message-ID to the clipboard.
+  var setupMessageIdButtonHandler = function () {
+
+    let messageIdClickHandler = (evt) => {
+      messageIdButton = evt.currentTarget;
+      originalTooltip = messageIdButton.dataset.tooltip;
+      var messageId = messageIdButton.dataset.messageId;
+      if (!window.isSecureContext) {
+	console.log("not in a secure context -- " +
+		    "cannot copy message-id to clipboard\n" +
+		    "tip: for testing, open via http://localhost:1234");
+	return;
+      }
+      // Update button's tooltip for the next 3 s.
+      messageIdButton.dataset.tooltip = "Copied!";
+      setTimeout(() => { messageIdButton.dataset.tooltip = originalTooltip; },
+		 3000);
+      navigator.clipboard.writeText(messageId);
+      console.log("copied Message-ID " + messageId + " to clipboard");
+    };
+
+    var messageIdButton = document.getElementById("copy-message-id-button");
+    if (messageIdButton === null) { return; }
+    messageIdButton.addEventListener("click", messageIdClickHandler);
+  };
+
   return({
     'init': init,
     'lines': setupLineHandler,
+    'messageIdButtonHandler': setupMessageIdButtonHandler,
   });
 })();
 
 window.addEventListener ("load", mumi.init);
 window.addEventListener ("DOMContentLoaded", mumi.lines);
+window.addEventListener ("DOMContentLoaded", mumi.messageIdButtonHandler);
 // @license-end
diff --git a/assets/mumi.scss b/assets/mumi.scss
index 822f110..60dabb1 100644
--- a/assets/mumi.scss
+++ b/assets/mumi.scss
@@ -506,11 +506,28 @@ details {
     margin-right: 0.2em;
 }
 
-.download-message,
 .download-part {
     float: right;
-    font-size: 0.8em;
-    font-style: italic;
+}
+
+.header-buttons {
+    display: flex;
+    flex-direction: row;
+    float: right;
+    justify-content: flex-end;
+ }
+
+.header-buttons > * {
+    margin: 0 0 0 0.5rem;
+    // Custom buttons: undo the Pico CSS default style.
+    background: revert;
+    border: revert;
+    color: revert;
+    padding: revert;
+}
+
+.message-button:hover {
+    transform: scale(0.95);
 }
 
 @media (min-width: 768px) {
diff --git a/mumi/web/view/html.scm b/mumi/web/view/html.scm
index 8f06a36..3709134 100644
--- a/mumi/web/view/html.scm
+++ b/mumi/web/view/html.scm
@@ -1,6 +1,7 @@
 ;;; mumi -- Mediocre, uh, mail interface
 ;;; Copyright © 2016, 2017, 2018, 2019, 2020, 2021, 2022 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2018, 2019, 2023 Arun Isaac <arunisaac@systemreboot.net>
+;;; Copyright © 2024 Maxim Cournoyer <maxim.cournoyer@gmail.com>
 ;;;
 ;;; This program is free software: you can redistribute it and/or
 ;;; modify it under the terms of the GNU Affero General Public License
@@ -612,6 +613,7 @@ currently disabled."))
                 (not (bug-archived bug)))
            mailer-form
            disabled-mailer)))
+
   (define (show-message message-number message previous-subject)
     `((div
        (a (@ (class "message-anchor")
@@ -642,10 +644,20 @@ currently disabled."))
                                                  message-number)))
                       (title ,(date->string (date message))))
                    ,(time->string (date message)))))
-         (div (@ (class "download-message"))
-              (a (@ (href ,(format #f "/issue/~a/raw/~a"
-                                   id message-number)))
-                 ,download-icon))
+         (div (@ (class "header-buttons"))
+              (div (@ (id "copy-message-id-button")
+                      (class "message-button")
+                      (role "button")   ;specific to Pico CSS
+                      (data-tooltip "Copy Message-ID")
+                      (data-message-id ,(message-id message)))
+                   ,copy-icon)
+              (div (@ (id "download-raw-message-button")
+                      (class "message-button")
+                      (role "button")
+                      (data-tooltip "Download raw message"))
+                   (a (@ (href ,(format #f "/issue/~a/raw/~a"
+                                        id message-number)))
+                      ,download-icon)))
          ,@(if (string-suffix? previous-subject (subject message))
                '()
                `((div (@ (class "subject")) ,(subject message))))
diff --git a/mumi/web/view/utils.scm b/mumi/web/view/utils.scm
index 1ce7b64..ed83d15 100644
--- a/mumi/web/view/utils.scm
+++ b/mumi/web/view/utils.scm
@@ -2,6 +2,7 @@
 ;;; Copyright © 2017, 2018, 2019, 2020 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2018, 2019 Arun Isaac <arunisaac@systemreboot.net>
 ;;; Copyright © 2018 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2024 Maxim Cournoyer <maxim.cournoyer@gmail.com>
 ;;;
 ;;; This program is free software: you can redistribute it and/or
 ;;; modify it under the terms of the GNU Affero General Public License
@@ -35,6 +36,7 @@
   #:use-module (web uri)
   #:export (prettify
             avatar-color
+            copy-icon
             download-icon
             display-message-body
             time->string))
@@ -215,23 +217,31 @@ numbers with the given MESSAGE-NUMBER."
 ;; https://icons.getbootstrap.com/icons/download/
 (define download-icon
   '(svg (@ (class "bi bi-download")
-           (width "1em")
-           (height "1em")
+           (width "1rem")
+           (height "1rem")
+           (viewBox "0 0 16 16")
+           (fill "currentColor")
+           (xmlns "http://www.w3.org/2000/svg"))
+        (path (@ (d "M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 \
+1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 \
+1-2-2v-2.5a.5.5 0 0 1 .5-.5")))
+        (path (@ (d "M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 \
+0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 \
+1 0-.708.708z")))))
+
+;; https://icons.getbootstrap.com/icons/copy/
+(define copy-icon
+  '(svg (@ (class "bi bi-copy")
+           (width "1rem")
+           (height "1rem")
            (viewBox "0 0 16 16")
            (fill "currentColor")
            (xmlns "http://www.w3.org/2000/svg"))
-        (title "Download")
-        (path (@ (fill-rule "evenodd")
-                 (clip-rule "evenodd")
-                 (d "M.5 8a.5.5 0 01.5.5V12a1 1 0 001 1h12a1 1 0 001-1\
-V8.5a.5.5 0 011 0V12a2 2 0 01-2 2H2a2 2 0 01-2-2V8.5A.5.5 0 01.5 8z")) "")
-        (path (@ (fill-rule "evenodd")
-                 (clip-rule "evenodd")
-                 (d "M5 7.5a.5.5 0 01.707 0L8 9.793 10.293 7.5a.5.5 0 \
-11.707.707l-2.646 2.647a.5.5 0 01-.708 0L5 8.207A.5.5 0 015 7.5z")) "")
         (path (@ (fill-rule "evenodd")
-                 (clip-rule "evenodd")
-                 (d "M8 1a.5.5 0 01.5.5v8a.5.5 0 01-1 0v-8A.5.5 0 018 1z")) "")))
+                 (d "M4 2a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H6a2 \
+2 0 0 1-2-2zm2-1a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V2a1 1 0 0 \
+0-1-1zM2 5a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1v-1h1v1a2 2 0 0 1-2 \
+2H2a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h1v1z")))))
 
 (define* (display-message-body bug-num message-number message #:optional plain?)
   "Convenience procedure to render MESSAGE (part of bug with number
@@ -285,7 +295,9 @@ lines when PLAIN? is #T."
                    "")))
        ((string-suffix? ".scm" attachment-name)
         `(div (@ (class "multipart scheme"))
-              (div (@ (class "download-part"))
+              (div (@ (id "download-scheme-part-button")
+                      (class "download-part message-button")
+                      (data-tooltip "Download Scheme file"))
                    (a (@ (href ,(attachment-url)))
                       ,download-icon))
               ,(highlights->sxml (highlight lex-scheme body))))
@@ -294,7 +306,9 @@ lines when PLAIN? is #T."
                           (list "multipart" (or (and content-type
                                                      (content-type->css-class content-type))
                                                 "")))))
-              (div (@ (class "download-part"))
+              (div (@ (id "download-part-button")
+                      (class "download-part message-button")
+                      (data-tooltip "Download MIME part"))
                    (a (@ (href ,(attachment-url)))
                       ,download-icon))
               ,(cond
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [bug#68680] [PATCH mumi 0/3] Add a button to copy a message Message-ID to the clipboard.
  2024-01-24  2:15 [bug#68680] [PATCH mumi 0/3] Add a button to copy a message Message-ID to the clipboard Maxim Cournoyer
  2024-01-24  2:20 ` [bug#68680] [PATCH mumi 1/3] README.org: Add new sections to help newcomers get started Maxim Cournoyer
@ 2024-01-24  2:29 ` Maxim Cournoyer
  2024-01-25 17:00 ` [bug#68680] [PATCH mumi v2 " Maxim Cournoyer
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 28+ messages in thread
From: Maxim Cournoyer @ 2024-01-24  2:29 UTC (permalink / raw)
  To: 68680; +Cc: Ricardo Wurmus, From Arun Isaac

+CC Ricardo and Arun in case they'd like to take a peek.

Maxim Cournoyer <maxim.cournoyer@gmail.com> writes:

> This series adds a new HTML element to each message header to easily
> copy the Message-ID of a message into the clipboard.  It makes use of
> the (already included) Pico CSS library for tooltips and some new
> JavaScript event handler.  The motivation was to make it easier to
> retrieve the Message-ID for passing it to the 'b4 shazam' command when
> applying long patches series.
>
>
> Maxim Cournoyer (3):
>   README.org: Add new sections to help newcomers get started.
>   .gitignore: Register mumi.xapian and signing-key files.
>   html: Add a button to copy a Message-ID to the clipboard.
>
>  .gitignore              |  2 ++
>  README.org              | 24 ++++++++++++++++++++++
>  assets/js/mumi.js       | 31 ++++++++++++++++++++++++++++-
>  assets/mumi.scss        | 23 ++++++++++++++++++---
>  mumi/web/view/html.scm  | 20 +++++++++++++++----
>  mumi/web/view/utils.scm | 44 +++++++++++++++++++++++++++--------------
>  6 files changed, 121 insertions(+), 23 deletions(-)
>
>
> base-commit: 025fc600f1cb4c73042bf920aee3e07d5fb9c53a

-- 
Thanks,
Maxim




^ permalink raw reply	[flat|nested] 28+ messages in thread

* [bug#68680] [PATCH mumi v2 0/3] Add a button to copy a message Message-ID to the clipboard.
  2024-01-24  2:15 [bug#68680] [PATCH mumi 0/3] Add a button to copy a message Message-ID to the clipboard Maxim Cournoyer
  2024-01-24  2:20 ` [bug#68680] [PATCH mumi 1/3] README.org: Add new sections to help newcomers get started Maxim Cournoyer
  2024-01-24  2:29 ` [bug#68680] [PATCH mumi 0/3] Add a button to copy a message " Maxim Cournoyer
@ 2024-01-25 17:00 ` Maxim Cournoyer
  2024-01-25 17:00   ` [bug#68680] [PATCH mumi v2 1/3] README.org: Add new sections to help newcomers get started Maxim Cournoyer
                     ` (3 more replies)
  2024-01-26  2:26 ` [bug#68680] [PATCH mumi v3 0/4] " Maxim Cournoyer
  2024-01-26 17:13 ` [bug#68680] [PATCH mumi v4 0/4] Add a button to copy a message " Maxim Cournoyer
  4 siblings, 4 replies; 28+ messages in thread
From: Maxim Cournoyer @ 2024-01-25 17:00 UTC (permalink / raw)
  To: 68680; +Cc: rekado, arunisaac, Maxim Cournoyer

This series adds a new HTML element to each message header to easily
copy the Message-ID of a message into the clipboard.  It makes use of
the (already included) Pico CSS library for tooltips and some new
JavaScript event handler.  The motivation was to make it easier to
retrieve the Message-ID for passing it to the 'b4 shazam' command when
applying long patches series.

Changes in v2:
 - Add timestamp to CSS and JavaScript file names to force reload

Maxim Cournoyer (3):
  README.org: Add new sections to help newcomers get started.
  .gitignore: Register mumi.xapian and signing-key files.
  html: Add a button to copy a Message-ID to the clipboard.

 .gitignore              |  2 ++
 README.org              | 24 ++++++++++++++++++++++
 assets/js/mumi.js       | 31 ++++++++++++++++++++++++++++-
 assets/mumi.scss        | 23 ++++++++++++++++++---
 mumi/web/view/html.scm  | 24 ++++++++++++++++------
 mumi/web/view/utils.scm | 44 +++++++++++++++++++++++++++--------------
 6 files changed, 123 insertions(+), 25 deletions(-)


base-commit: 025fc600f1cb4c73042bf920aee3e07d5fb9c53a
-- 
2.41.0





^ permalink raw reply	[flat|nested] 28+ messages in thread

* [bug#68680] [PATCH mumi v2 1/3] README.org: Add new sections to help newcomers get started.
  2024-01-25 17:00 ` [bug#68680] [PATCH mumi v2 " Maxim Cournoyer
@ 2024-01-25 17:00   ` Maxim Cournoyer
  2024-01-26 21:18     ` Arun Isaac
  2024-01-25 17:00   ` [bug#68680] [PATCH mumi v2 2/3] .gitignore: Register mumi.xapian and signing-key files Maxim Cournoyer
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 28+ messages in thread
From: Maxim Cournoyer @ 2024-01-25 17:00 UTC (permalink / raw)
  To: 68680; +Cc: rekado, arunisaac, Maxim Cournoyer

* README.org (Running a local instance of mumi): New section.
(Disabling browser caching): Likewise.
---

(no changes since v1)

 README.org | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/README.org b/README.org
index fd1d77b..d092de7 100644
--- a/README.org
+++ b/README.org
@@ -11,3 +11,27 @@ run
 #+BEGIN_SRC shell
   $ guix shell -D mumi
 #+END_SRC
+
+** Running a local instance of mumi
+
+First copy some test mail data to be indexed:
+
+#+begin_src shell
+  $ cp -a tests/data data
+#+end_src
+
+Then, to have these emails indexed, run:
+
+#+begin_src shell
+  $ ./pre-inst-env mumi fetch
+#+end_src
+
+You should now be able to visit http://0.0.0.0:1234 in your browser
+and see your local mumi instance running.
+
+** Disabling browser caching
+
+If you modify the CSS or JavaScript source files, you'll want to make
+sure your browser doesn't keep cached copies.  This can be done by
+changing a preference in the development tools menus, which is called
+something like "Disable cache (while DevTools is active)".
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [bug#68680] [PATCH mumi v2 2/3] .gitignore: Register mumi.xapian and signing-key files.
  2024-01-25 17:00 ` [bug#68680] [PATCH mumi v2 " Maxim Cournoyer
  2024-01-25 17:00   ` [bug#68680] [PATCH mumi v2 1/3] README.org: Add new sections to help newcomers get started Maxim Cournoyer
@ 2024-01-25 17:00   ` Maxim Cournoyer
  2024-01-25 17:00   ` [bug#68680] [PATCH mumi v2 3/3] html: Add a button to copy a Message-ID to the clipboard Maxim Cournoyer
  2024-01-26 21:21   ` [bug#68680] [PATCH mumi v2 0/3] Add a button to copy a message " Arun Isaac
  3 siblings, 0 replies; 28+ messages in thread
From: Maxim Cournoyer @ 2024-01-25 17:00 UTC (permalink / raw)
  To: 68680; +Cc: rekado, arunisaac, Maxim Cournoyer

---

(no changes since v1)

 .gitignore | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.gitignore b/.gitignore
index 2604e48..7247392 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,8 +8,10 @@ config.log
 config.status
 configure
 
+mumi.xapian
 mumi/config.scm
 scripts/mumi
+signing-key
 pre-inst-env
 *.log
 *.trs
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [bug#68680] [PATCH mumi v2 3/3] html: Add a button to copy a Message-ID to the clipboard.
  2024-01-25 17:00 ` [bug#68680] [PATCH mumi v2 " Maxim Cournoyer
  2024-01-25 17:00   ` [bug#68680] [PATCH mumi v2 1/3] README.org: Add new sections to help newcomers get started Maxim Cournoyer
  2024-01-25 17:00   ` [bug#68680] [PATCH mumi v2 2/3] .gitignore: Register mumi.xapian and signing-key files Maxim Cournoyer
@ 2024-01-25 17:00   ` Maxim Cournoyer
  2024-01-26 21:21   ` [bug#68680] [PATCH mumi v2 0/3] Add a button to copy a message " Arun Isaac
  3 siblings, 0 replies; 28+ messages in thread
From: Maxim Cournoyer @ 2024-01-25 17:00 UTC (permalink / raw)
  To: 68680; +Cc: rekado, arunisaac, Maxim Cournoyer

* mumi/web/view/html.scm (issue-page)
<copy-message-id-button>: New HTML element.
(layout): Bump timestamp on .css and .js files to force reload.
* mumi/web/view/utils.scm (download-icon): Update source.  Use 'rem'
as size unit.
(copy-icon): New variable.
(display-message-body) <download-part>: Add IDs to buttons.  Add to
"message-button" class.
* assets/mumi.scss: Refactor spacing of message header buttons via a
flex display.  Add a shrinking animation to message buttons on hover.
* assets/js/mumi.js (mumi): Register an event for it that copies the
Message-ID to the clipboard.  Add js-indent-level prop line.
* mumi/web/view/html.scm

---

Changes in v2:
 - Add timestamp to CSS and JavaScript file names to force reload

 assets/js/mumi.js       | 31 ++++++++++++++++++++++++++++-
 assets/mumi.scss        | 23 ++++++++++++++++++---
 mumi/web/view/html.scm  | 24 ++++++++++++++++------
 mumi/web/view/utils.scm | 44 +++++++++++++++++++++++++++--------------
 4 files changed, 97 insertions(+), 25 deletions(-)

diff --git a/assets/js/mumi.js b/assets/js/mumi.js
index ab29f08..0d25c5a 100644
--- a/assets/js/mumi.js
+++ b/assets/js/mumi.js
@@ -1,4 +1,4 @@
-// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3.0-or-later
+// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3.0-or-later  -*- js-indent-level: 2; -*-
 var mumi = (function () {
   const possibleTokens = [
     { text: 'is:open' },
@@ -129,12 +129,41 @@ var mumi = (function () {
   var init = function () {
     initTokenInput ();
   };
+
+  // Copy a message Message-ID to the clipboard.
+  var setupMessageIdButtonHandler = function () {
+
+    let messageIdClickHandler = (evt) => {
+      messageIdButton = evt.currentTarget;
+      originalTooltip = messageIdButton.dataset.tooltip;
+      var messageId = messageIdButton.dataset.messageId;
+      if (!window.isSecureContext) {
+	console.log("not in a secure context -- " +
+		    "cannot copy message-id to clipboard\n" +
+		    "tip: for testing, open via http://localhost:1234");
+	return;
+      }
+      // Update button's tooltip for the next 3 s.
+      messageIdButton.dataset.tooltip = "Copied!";
+      setTimeout(() => { messageIdButton.dataset.tooltip = originalTooltip; },
+		 3000);
+      navigator.clipboard.writeText(messageId);
+      console.log("copied Message-ID " + messageId + " to clipboard");
+    };
+
+    var messageIdButton = document.getElementById("copy-message-id-button");
+    if (messageIdButton === null) { return; }
+    messageIdButton.addEventListener("click", messageIdClickHandler);
+  };
+
   return({
     'init': init,
     'lines': setupLineHandler,
+    'messageIdButtonHandler': setupMessageIdButtonHandler,
   });
 })();
 
 window.addEventListener ("load", mumi.init);
 window.addEventListener ("DOMContentLoaded", mumi.lines);
+window.addEventListener ("DOMContentLoaded", mumi.messageIdButtonHandler);
 // @license-end
diff --git a/assets/mumi.scss b/assets/mumi.scss
index 822f110..60dabb1 100644
--- a/assets/mumi.scss
+++ b/assets/mumi.scss
@@ -506,11 +506,28 @@ details {
     margin-right: 0.2em;
 }
 
-.download-message,
 .download-part {
     float: right;
-    font-size: 0.8em;
-    font-style: italic;
+}
+
+.header-buttons {
+    display: flex;
+    flex-direction: row;
+    float: right;
+    justify-content: flex-end;
+ }
+
+.header-buttons > * {
+    margin: 0 0 0 0.5rem;
+    // Custom buttons: undo the Pico CSS default style.
+    background: revert;
+    border: revert;
+    color: revert;
+    padding: revert;
+}
+
+.message-button:hover {
+    transform: scale(0.95);
 }
 
 @media (min-width: 768px) {
diff --git a/mumi/web/view/html.scm b/mumi/web/view/html.scm
index 8f06a36..b9603ec 100644
--- a/mumi/web/view/html.scm
+++ b/mumi/web/view/html.scm
@@ -1,6 +1,7 @@
 ;;; mumi -- Mediocre, uh, mail interface
 ;;; Copyright © 2016, 2017, 2018, 2019, 2020, 2021, 2022 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2018, 2019, 2023 Arun Isaac <arunisaac@systemreboot.net>
+;;; Copyright © 2024 Maxim Cournoyer <maxim.cournoyer@gmail.com>
 ;;;
 ;;; This program is free software: you can redistribute it and/or
 ;;; modify it under the terms of the GNU Affero General Public License
@@ -62,11 +63,11 @@
        (@ (rel "stylesheet")
           (media "screen")
           (type "text/css")
-          (href "/css/mumi.css?20221231000000")))
+          (href "/css/mumi.css?20240125000000")))
       (script
        (@ (src "/js/tokeninput.js")))
       (script
-       (@ (src "/js/mumi.js")))
+       (@ (src "/js/mumi.js?20240125000000")))
       ,@head)
      (body (script
             (@ (src "/js/theme-switcher.js")))
@@ -612,6 +613,7 @@ currently disabled."))
                 (not (bug-archived bug)))
            mailer-form
            disabled-mailer)))
+
   (define (show-message message-number message previous-subject)
     `((div
        (a (@ (class "message-anchor")
@@ -642,10 +644,20 @@ currently disabled."))
                                                  message-number)))
                       (title ,(date->string (date message))))
                    ,(time->string (date message)))))
-         (div (@ (class "download-message"))
-              (a (@ (href ,(format #f "/issue/~a/raw/~a"
-                                   id message-number)))
-                 ,download-icon))
+         (div (@ (class "header-buttons"))
+              (div (@ (id "copy-message-id-button")
+                      (class "message-button")
+                      (role "button")   ;specific to Pico CSS
+                      (data-tooltip "Copy Message-ID")
+                      (data-message-id ,(message-id message)))
+                   ,copy-icon)
+              (div (@ (id "download-raw-message-button")
+                      (class "message-button")
+                      (role "button")
+                      (data-tooltip "Download raw message"))
+                   (a (@ (href ,(format #f "/issue/~a/raw/~a"
+                                        id message-number)))
+                      ,download-icon)))
          ,@(if (string-suffix? previous-subject (subject message))
                '()
                `((div (@ (class "subject")) ,(subject message))))
diff --git a/mumi/web/view/utils.scm b/mumi/web/view/utils.scm
index 1ce7b64..ed83d15 100644
--- a/mumi/web/view/utils.scm
+++ b/mumi/web/view/utils.scm
@@ -2,6 +2,7 @@
 ;;; Copyright © 2017, 2018, 2019, 2020 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2018, 2019 Arun Isaac <arunisaac@systemreboot.net>
 ;;; Copyright © 2018 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2024 Maxim Cournoyer <maxim.cournoyer@gmail.com>
 ;;;
 ;;; This program is free software: you can redistribute it and/or
 ;;; modify it under the terms of the GNU Affero General Public License
@@ -35,6 +36,7 @@
   #:use-module (web uri)
   #:export (prettify
             avatar-color
+            copy-icon
             download-icon
             display-message-body
             time->string))
@@ -215,23 +217,31 @@ numbers with the given MESSAGE-NUMBER."
 ;; https://icons.getbootstrap.com/icons/download/
 (define download-icon
   '(svg (@ (class "bi bi-download")
-           (width "1em")
-           (height "1em")
+           (width "1rem")
+           (height "1rem")
+           (viewBox "0 0 16 16")
+           (fill "currentColor")
+           (xmlns "http://www.w3.org/2000/svg"))
+        (path (@ (d "M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 \
+1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 \
+1-2-2v-2.5a.5.5 0 0 1 .5-.5")))
+        (path (@ (d "M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 \
+0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 \
+1 0-.708.708z")))))
+
+;; https://icons.getbootstrap.com/icons/copy/
+(define copy-icon
+  '(svg (@ (class "bi bi-copy")
+           (width "1rem")
+           (height "1rem")
            (viewBox "0 0 16 16")
            (fill "currentColor")
            (xmlns "http://www.w3.org/2000/svg"))
-        (title "Download")
-        (path (@ (fill-rule "evenodd")
-                 (clip-rule "evenodd")
-                 (d "M.5 8a.5.5 0 01.5.5V12a1 1 0 001 1h12a1 1 0 001-1\
-V8.5a.5.5 0 011 0V12a2 2 0 01-2 2H2a2 2 0 01-2-2V8.5A.5.5 0 01.5 8z")) "")
-        (path (@ (fill-rule "evenodd")
-                 (clip-rule "evenodd")
-                 (d "M5 7.5a.5.5 0 01.707 0L8 9.793 10.293 7.5a.5.5 0 \
-11.707.707l-2.646 2.647a.5.5 0 01-.708 0L5 8.207A.5.5 0 015 7.5z")) "")
         (path (@ (fill-rule "evenodd")
-                 (clip-rule "evenodd")
-                 (d "M8 1a.5.5 0 01.5.5v8a.5.5 0 01-1 0v-8A.5.5 0 018 1z")) "")))
+                 (d "M4 2a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H6a2 \
+2 0 0 1-2-2zm2-1a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V2a1 1 0 0 \
+0-1-1zM2 5a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1v-1h1v1a2 2 0 0 1-2 \
+2H2a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h1v1z")))))
 
 (define* (display-message-body bug-num message-number message #:optional plain?)
   "Convenience procedure to render MESSAGE (part of bug with number
@@ -285,7 +295,9 @@ lines when PLAIN? is #T."
                    "")))
        ((string-suffix? ".scm" attachment-name)
         `(div (@ (class "multipart scheme"))
-              (div (@ (class "download-part"))
+              (div (@ (id "download-scheme-part-button")
+                      (class "download-part message-button")
+                      (data-tooltip "Download Scheme file"))
                    (a (@ (href ,(attachment-url)))
                       ,download-icon))
               ,(highlights->sxml (highlight lex-scheme body))))
@@ -294,7 +306,9 @@ lines when PLAIN? is #T."
                           (list "multipart" (or (and content-type
                                                      (content-type->css-class content-type))
                                                 "")))))
-              (div (@ (class "download-part"))
+              (div (@ (id "download-part-button")
+                      (class "download-part message-button")
+                      (data-tooltip "Download MIME part"))
                    (a (@ (href ,(attachment-url)))
                       ,download-icon))
               ,(cond
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [bug#68680] [PATCH mumi v3 0/4] Add a button to copy a message Message-ID to the clipboard.
  2024-01-24  2:15 [bug#68680] [PATCH mumi 0/3] Add a button to copy a message Message-ID to the clipboard Maxim Cournoyer
                   ` (2 preceding siblings ...)
  2024-01-25 17:00 ` [bug#68680] [PATCH mumi v2 " Maxim Cournoyer
@ 2024-01-26  2:26 ` Maxim Cournoyer
  2024-01-26  2:26   ` [bug#68680] [PATCH mumi v3 1/4] README.org: Add new sections to help newcomers get started Maxim Cournoyer
                     ` (3 more replies)
  2024-01-26 17:13 ` [bug#68680] [PATCH mumi v4 0/4] Add a button to copy a message " Maxim Cournoyer
  4 siblings, 4 replies; 28+ messages in thread
From: Maxim Cournoyer @ 2024-01-26  2:26 UTC (permalink / raw)
  To: 68680; +Cc: rekado, arunisaac, Maxim Cournoyer

This series adds a new HTML element to each message header to easily
copy the Message-ID of a message into the clipboard.  It makes use of
the (already included) Pico CSS library for tooltips and some new
JavaScript event handler.  The motivation was to make it easier to
retrieve the Message-ID for passing it to the 'b4 shazam' command when
applying long patches series.

Changes in v3:
 - Allow using the new copy button via the keyboard
 - Register event handlers on all copy message-id buttons
 - Move download icon sizes to CSS to resolve warning in Firefox
 - Add guard inside download button event to ensure only one event
   runs at a time, avoiding tooltip getting stuck on 'Copied!'
 - Use a class name instead of a unique ID for the message-id buttons
 - Register handlers to every message-id buttons

Changes in v2:
 - Add timestamp to CSS and JavaScript file names to force reload

Maxim Cournoyer (4):
  README.org: Add new sections to help newcomers get started.
  .gitignore: Register mumi.xapian and signing-key files.
  Add .patman configuration file.
  html: Add a button to copy a Message-ID to the clipboard.

 .gitignore              |  2 ++
 .patman                 |  7 +++++
 README.org              | 24 +++++++++++++++++
 assets/js/mumi.js       | 59 ++++++++++++++++++++++++++++++++++++++++-
 assets/mumi.scss        | 28 ++++++++++++++++---
 mumi/web/view/html.scm  | 24 ++++++++++++-----
 mumi/web/view/utils.scm | 40 +++++++++++++++++-----------
 7 files changed, 159 insertions(+), 25 deletions(-)
 create mode 100644 .patman


base-commit: 025fc600f1cb4c73042bf920aee3e07d5fb9c53a
-- 
2.41.0





^ permalink raw reply	[flat|nested] 28+ messages in thread

* [bug#68680] [PATCH mumi v3 1/4] README.org: Add new sections to help newcomers get started.
  2024-01-26  2:26 ` [bug#68680] [PATCH mumi v3 0/4] " Maxim Cournoyer
@ 2024-01-26  2:26   ` Maxim Cournoyer
  2024-01-26  2:26   ` [bug#68680] [PATCH mumi v3 2/4] .gitignore: Register mumi.xapian and signing-key files Maxim Cournoyer
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 28+ messages in thread
From: Maxim Cournoyer @ 2024-01-26  2:26 UTC (permalink / raw)
  To: 68680; +Cc: rekado, arunisaac, Maxim Cournoyer

* README.org (Running a local instance of mumi): New section.
(Disabling browser caching): Likewise.
---

(no changes since v1)

 README.org | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/README.org b/README.org
index fd1d77b..d092de7 100644
--- a/README.org
+++ b/README.org
@@ -11,3 +11,27 @@ run
 #+BEGIN_SRC shell
   $ guix shell -D mumi
 #+END_SRC
+
+** Running a local instance of mumi
+
+First copy some test mail data to be indexed:
+
+#+begin_src shell
+  $ cp -a tests/data data
+#+end_src
+
+Then, to have these emails indexed, run:
+
+#+begin_src shell
+  $ ./pre-inst-env mumi fetch
+#+end_src
+
+You should now be able to visit http://0.0.0.0:1234 in your browser
+and see your local mumi instance running.
+
+** Disabling browser caching
+
+If you modify the CSS or JavaScript source files, you'll want to make
+sure your browser doesn't keep cached copies.  This can be done by
+changing a preference in the development tools menus, which is called
+something like "Disable cache (while DevTools is active)".
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [bug#68680] [PATCH mumi v3 2/4] .gitignore: Register mumi.xapian and signing-key files.
  2024-01-26  2:26 ` [bug#68680] [PATCH mumi v3 0/4] " Maxim Cournoyer
  2024-01-26  2:26   ` [bug#68680] [PATCH mumi v3 1/4] README.org: Add new sections to help newcomers get started Maxim Cournoyer
@ 2024-01-26  2:26   ` Maxim Cournoyer
  2024-01-26  2:26   ` [bug#68680] [PATCH mumi v3 3/4] Add .patman configuration file Maxim Cournoyer
  2024-01-26  2:26   ` [bug#68680] [PATCH mumi v3 4/4] html: Add a button to copy a Message-ID to the clipboard Maxim Cournoyer
  3 siblings, 0 replies; 28+ messages in thread
From: Maxim Cournoyer @ 2024-01-26  2:26 UTC (permalink / raw)
  To: 68680; +Cc: rekado, arunisaac, Maxim Cournoyer

---

(no changes since v1)

 .gitignore | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.gitignore b/.gitignore
index 2604e48..7247392 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,8 +8,10 @@ config.log
 config.status
 configure
 
+mumi.xapian
 mumi/config.scm
 scripts/mumi
+signing-key
 pre-inst-env
 *.log
 *.trs
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [bug#68680] [PATCH mumi v3 3/4] Add .patman configuration file.
  2024-01-26  2:26 ` [bug#68680] [PATCH mumi v3 0/4] " Maxim Cournoyer
  2024-01-26  2:26   ` [bug#68680] [PATCH mumi v3 1/4] README.org: Add new sections to help newcomers get started Maxim Cournoyer
  2024-01-26  2:26   ` [bug#68680] [PATCH mumi v3 2/4] .gitignore: Register mumi.xapian and signing-key files Maxim Cournoyer
@ 2024-01-26  2:26   ` Maxim Cournoyer
  2024-01-26  2:26   ` [bug#68680] [PATCH mumi v3 4/4] html: Add a button to copy a Message-ID to the clipboard Maxim Cournoyer
  3 siblings, 0 replies; 28+ messages in thread
From: Maxim Cournoyer @ 2024-01-26  2:26 UTC (permalink / raw)
  To: 68680; +Cc: rekado, arunisaac, Maxim Cournoyer

* .patman: New file.
---

(no changes since v1)

 .patman | 7 +++++++
 1 file changed, 7 insertions(+)
 create mode 100644 .patman

diff --git a/.patman b/.patman
new file mode 100644
index 0000000..87b96e9
--- /dev/null
+++ b/.patman
@@ -0,0 +1,7 @@
+[settings]
+project: guix-patches
+patchwork_url: https://patches.guix-patches.cbaines.net
+add_signoff: False
+check_patch: False
+ignore_bad_tags: True
+keep_change_id: True
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [bug#68680] [PATCH mumi v3 4/4] html: Add a button to copy a Message-ID to the clipboard.
  2024-01-26  2:26 ` [bug#68680] [PATCH mumi v3 0/4] " Maxim Cournoyer
                     ` (2 preceding siblings ...)
  2024-01-26  2:26   ` [bug#68680] [PATCH mumi v3 3/4] Add .patman configuration file Maxim Cournoyer
@ 2024-01-26  2:26   ` Maxim Cournoyer
  3 siblings, 0 replies; 28+ messages in thread
From: Maxim Cournoyer @ 2024-01-26  2:26 UTC (permalink / raw)
  To: 68680; +Cc: rekado, arunisaac, Maxim Cournoyer

* mumi/web/view/html.scm (issue-page)
<copy-message-id-button>: New HTML element.
(layout): Bump timestamp on .css and .js files to force reload.
* mumi/web/view/utils.scm (download-icon): Update source.  Use 'rem'
as size unit.
(copy-icon): New variable.
(display-message-body) <download-part>: Add IDs to buttons.  Add to
"message-button" class.
* assets/mumi.scss: Refactor spacing of message header buttons via a
flex display.  Add a shrinking animation to message buttons on hover.
* assets/js/mumi.js (mumi): Register an event for it that copies the
Message-ID to the clipboard.  Add js-indent-level prop line as well as
copyright notices.
* mumi/web/view/html.scm

---

Changes in v3:
 - Allow using the new copy button via the keyboard
 - Register event handlers on all copy message-id buttons
 - Move download icon sizes to CSS to resolve warning in Firefox
 - Add guard inside download button event to ensure only one event
   runs at a time, avoiding tooltip getting stuck on 'Copied!'
 - Use a class name instead of a unique ID for the message-id buttons
 - Register handlers to every message-id buttons

Changes in v2:
 - Add timestamp to CSS and JavaScript file names to force reload

 assets/js/mumi.js       | 59 ++++++++++++++++++++++++++++++++++++++++-
 assets/mumi.scss        | 28 ++++++++++++++++---
 mumi/web/view/html.scm  | 24 ++++++++++++-----
 mumi/web/view/utils.scm | 40 +++++++++++++++++-----------
 4 files changed, 126 insertions(+), 25 deletions(-)

diff --git a/assets/js/mumi.js b/assets/js/mumi.js
index ab29f08..77b9276 100644
--- a/assets/js/mumi.js
+++ b/assets/js/mumi.js
@@ -1,4 +1,8 @@
-// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3.0-or-later
+// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3.0-or-later  -*- js-indent-level: 2; -*-
+//
+// Copyright © 2019, 2022, 2023 Ricardo Wurmus <rekado@elephly.net>
+// Copyright © 2024 Maxim Cournoyer <maxim.cournoyer@gmail.com>
+//
 var mumi = (function () {
   const possibleTokens = [
     { text: 'is:open' },
@@ -129,12 +133,65 @@ var mumi = (function () {
   var init = function () {
     initTokenInput ();
   };
+
+  // Copy a message Message-ID to the clipboard.
+  var setupMessageIdButtonHandler = () => {
+
+    // Avoid having the async timeout code starting while a previous
+    // one is ongoing, which would corrupt the tooltip text.
+    var isMessageIdHandlerRunning = false;
+
+    let messageIdHandler = (evt) => {
+      if (isMessageIdHandlerRunning) return;
+      isMessageIdHandlerRunning = true;
+
+      // If the button was triggered by a keyup event, check if it was
+      // the Enter key.
+      if (evt.type === "keyup" && event.key !== "Enter") return;
+
+      messageIdButton = evt.currentTarget;
+      originalTooltip = messageIdButton.dataset.tooltip;
+      var messageId = messageIdButton.dataset.messageId;
+      if (!window.isSecureContext) {
+	console.log("not in a secure context -- " +
+		    "cannot copy message-id to clipboard\n" +
+		    "tip: for testing, open via http://localhost:1234");
+	return;
+      }
+
+      // Avoid the button being stuck in the focused state when a
+      // mouse is used, to avoid UI clutter.
+      if (evt.type === "click") {
+	messageIdButton.removeAttribute('tabindex');
+      }
+
+      // Update button's tooltip for the next 3 s.
+      messageIdButton.dataset.tooltip = "Copied!";
+      setTimeout(() => {
+	messageIdButton.dataset.tooltip = originalTooltip;
+	if (evt.type === "click") {
+	  // Re-add the tabindex attribute.
+	  messageIdButton.setAttribute("tabindex", "0")
+	  isMessageIdHandlerRunning = false;
+	}}, 3000);
+
+      navigator.clipboard.writeText(messageId);
+      console.log("copied Message-ID " + messageId + " to clipboard");
+    };
+
+    document.querySelectorAll(".copy-message-id-button").forEach((btn) => {
+      btn.addEventListener("click", messageIdHandler);
+      btn.addEventListener("keyup", messageIdHandler)});
+  };
+
   return({
     'init': init,
     'lines': setupLineHandler,
+    'messageIdButtonHandler': setupMessageIdButtonHandler,
   });
 })();
 
 window.addEventListener ("load", mumi.init);
 window.addEventListener ("DOMContentLoaded", mumi.lines);
+window.addEventListener ("DOMContentLoaded", mumi.messageIdButtonHandler);
 // @license-end
diff --git a/assets/mumi.scss b/assets/mumi.scss
index 822f110..b12a733 100644
--- a/assets/mumi.scss
+++ b/assets/mumi.scss
@@ -506,11 +506,33 @@ details {
     margin-right: 0.2em;
 }
 
-.download-message,
 .download-part {
     float: right;
-    font-size: 0.8em;
-    font-style: italic;
+}
+
+.header-buttons {
+    display: flex;
+    flex-direction: row;
+    float: right;
+    justify-content: flex-end;
+ }
+
+.header-buttons > * {
+    margin: 0 0 0 0.5rem;
+    // Custom buttons: undo the Pico CSS default style.
+    background: revert;
+    border: revert;
+    color: revert;
+    padding: revert;
+}
+
+.message-button {
+    height: 1rem;
+    width: 1rem;
+}
+
+.message-button:hover {
+    transform: scale(0.95);
 }
 
 @media (min-width: 768px) {
diff --git a/mumi/web/view/html.scm b/mumi/web/view/html.scm
index 8f06a36..8ae1a6f 100644
--- a/mumi/web/view/html.scm
+++ b/mumi/web/view/html.scm
@@ -1,6 +1,7 @@
 ;;; mumi -- Mediocre, uh, mail interface
 ;;; Copyright © 2016, 2017, 2018, 2019, 2020, 2021, 2022 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2018, 2019, 2023 Arun Isaac <arunisaac@systemreboot.net>
+;;; Copyright © 2024 Maxim Cournoyer <maxim.cournoyer@gmail.com>
 ;;;
 ;;; This program is free software: you can redistribute it and/or
 ;;; modify it under the terms of the GNU Affero General Public License
@@ -62,11 +63,11 @@
        (@ (rel "stylesheet")
           (media "screen")
           (type "text/css")
-          (href "/css/mumi.css?20221231000000")))
+          (href "/css/mumi.css?20240125000002")))
       (script
        (@ (src "/js/tokeninput.js")))
       (script
-       (@ (src "/js/mumi.js")))
+       (@ (src "/js/mumi.js?20240125000002")))
       ,@head)
      (body (script
             (@ (src "/js/theme-switcher.js")))
@@ -612,6 +613,7 @@ currently disabled."))
                 (not (bug-archived bug)))
            mailer-form
            disabled-mailer)))
+
   (define (show-message message-number message previous-subject)
     `((div
        (a (@ (class "message-anchor")
@@ -642,10 +644,20 @@ currently disabled."))
                                                  message-number)))
                       (title ,(date->string (date message))))
                    ,(time->string (date message)))))
-         (div (@ (class "download-message"))
-              (a (@ (href ,(format #f "/issue/~a/raw/~a"
-                                   id message-number)))
-                 ,download-icon))
+         (div (@ (class "header-buttons"))
+              (div (@ (class "copy-message-id-button message-button")
+                      (tabindex "0")    ;make it keyboard-usable
+                      (role "button")   ;specific to Pico CSS
+                      (data-tooltip "Copy Message-ID")
+                      (data-message-id ,(message-id message)))
+                   ,copy-icon)
+              (div (@ (id "download-raw-message-button")
+                      (class "message-button")
+                      (role "button")
+                      (data-tooltip "Download raw message"))
+                   (a (@ (href ,(format #f "/issue/~a/raw/~a"
+                                        id message-number)))
+                      ,download-icon)))
          ,@(if (string-suffix? previous-subject (subject message))
                '()
                `((div (@ (class "subject")) ,(subject message))))
diff --git a/mumi/web/view/utils.scm b/mumi/web/view/utils.scm
index 1ce7b64..712d198 100644
--- a/mumi/web/view/utils.scm
+++ b/mumi/web/view/utils.scm
@@ -2,6 +2,7 @@
 ;;; Copyright © 2017, 2018, 2019, 2020 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2018, 2019 Arun Isaac <arunisaac@systemreboot.net>
 ;;; Copyright © 2018 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2024 Maxim Cournoyer <maxim.cournoyer@gmail.com>
 ;;;
 ;;; This program is free software: you can redistribute it and/or
 ;;; modify it under the terms of the GNU Affero General Public License
@@ -35,6 +36,7 @@
   #:use-module (web uri)
   #:export (prettify
             avatar-color
+            copy-icon
             download-icon
             display-message-body
             time->string))
@@ -215,23 +217,27 @@ numbers with the given MESSAGE-NUMBER."
 ;; https://icons.getbootstrap.com/icons/download/
 (define download-icon
   '(svg (@ (class "bi bi-download")
-           (width "1em")
-           (height "1em")
            (viewBox "0 0 16 16")
            (fill "currentColor")
            (xmlns "http://www.w3.org/2000/svg"))
-        (title "Download")
-        (path (@ (fill-rule "evenodd")
-                 (clip-rule "evenodd")
-                 (d "M.5 8a.5.5 0 01.5.5V12a1 1 0 001 1h12a1 1 0 001-1\
-V8.5a.5.5 0 011 0V12a2 2 0 01-2 2H2a2 2 0 01-2-2V8.5A.5.5 0 01.5 8z")) "")
-        (path (@ (fill-rule "evenodd")
-                 (clip-rule "evenodd")
-                 (d "M5 7.5a.5.5 0 01.707 0L8 9.793 10.293 7.5a.5.5 0 \
-11.707.707l-2.646 2.647a.5.5 0 01-.708 0L5 8.207A.5.5 0 015 7.5z")) "")
+        (path (@ (d "M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 \
+1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 \
+1-2-2v-2.5a.5.5 0 0 1 .5-.5")))
+        (path (@ (d "M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 \
+0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 \
+1 0-.708.708z")))))
+
+;; https://icons.getbootstrap.com/icons/copy/
+(define copy-icon
+  '(svg (@ (class "bi bi-copy")
+           (viewBox "0 0 16 16")
+           (fill "currentColor")
+           (xmlns "http://www.w3.org/2000/svg"))
         (path (@ (fill-rule "evenodd")
-                 (clip-rule "evenodd")
-                 (d "M8 1a.5.5 0 01.5.5v8a.5.5 0 01-1 0v-8A.5.5 0 018 1z")) "")))
+                 (d "M4 2a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H6a2 \
+2 0 0 1-2-2zm2-1a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V2a1 1 0 0 \
+0-1-1zM2 5a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1v-1h1v1a2 2 0 0 1-2 \
+2H2a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h1v1z")))))
 
 (define* (display-message-body bug-num message-number message #:optional plain?)
   "Convenience procedure to render MESSAGE (part of bug with number
@@ -285,7 +291,9 @@ lines when PLAIN? is #T."
                    "")))
        ((string-suffix? ".scm" attachment-name)
         `(div (@ (class "multipart scheme"))
-              (div (@ (class "download-part"))
+              (div (@ (id "download-scheme-part-button")
+                      (class "download-part message-button")
+                      (data-tooltip "Download Scheme file"))
                    (a (@ (href ,(attachment-url)))
                       ,download-icon))
               ,(highlights->sxml (highlight lex-scheme body))))
@@ -294,7 +302,9 @@ lines when PLAIN? is #T."
                           (list "multipart" (or (and content-type
                                                      (content-type->css-class content-type))
                                                 "")))))
-              (div (@ (class "download-part"))
+              (div (@ (id "download-part-button")
+                      (class "download-part message-button")
+                      (data-tooltip "Download MIME part"))
                    (a (@ (href ,(attachment-url)))
                       ,download-icon))
               ,(cond
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [bug#68680] [PATCH mumi v4 0/4] Add a button to copy a message Message-ID to the clipboard.
  2024-01-24  2:15 [bug#68680] [PATCH mumi 0/3] Add a button to copy a message Message-ID to the clipboard Maxim Cournoyer
                   ` (3 preceding siblings ...)
  2024-01-26  2:26 ` [bug#68680] [PATCH mumi v3 0/4] " Maxim Cournoyer
@ 2024-01-26 17:13 ` Maxim Cournoyer
  2024-01-26 17:13   ` [bug#68680] [PATCH mumi v4 1/4] README.org: Add new sections to help newcomers get started Maxim Cournoyer
                     ` (3 more replies)
  4 siblings, 4 replies; 28+ messages in thread
From: Maxim Cournoyer @ 2024-01-26 17:13 UTC (permalink / raw)
  To: 68680; +Cc: rekado, arunisaac, Maxim Cournoyer

This series adds a new HTML element to each message header to easily
copy the Message-ID of a message into the clipboard.  It makes use of
the (already included) Pico CSS library for tooltips and some new
JavaScript event handler.  The motivation was to make it easier to
retrieve the Message-ID for passing it to the 'b4 shazam' command when
applying long patches series.

I've deployed it on Berlin, so anyone can try it already and provide feedback.

Changes in v4:
 - Set icon sizes via CSS instead of HTML, which improves layout

Changes in v3:
 - Allow using the new copy button via the keyboard
 - Register event handlers on all copy message-id buttons
 - Move download icon sizes to CSS to resolve warning in Firefox
 - Add guard inside download button event to ensure only one event
   runs at a time, avoiding tooltip getting stuck on 'Copied!'
 - Use a class name instead of a unique ID for the message-id buttons
 - Register handlers to every message-id buttons

Changes in v2:
 - Add timestamp to CSS and JavaScript file names to force reload

Maxim Cournoyer (4):
  README.org: Add new sections to help newcomers get started.
  .gitignore: Register mumi.xapian and signing-key files.
  Add .patman configuration file.
  html: Add a button to copy a Message-ID to the clipboard.

 .gitignore              |  2 ++
 .patman                 |  7 +++++
 README.org              | 24 +++++++++++++++++
 assets/js/mumi.js       | 59 ++++++++++++++++++++++++++++++++++++++++-
 assets/mumi.scss        | 31 +++++++++++++++++++---
 mumi/web/view/html.scm  | 24 ++++++++++++-----
 mumi/web/view/utils.scm | 40 +++++++++++++++++-----------
 7 files changed, 162 insertions(+), 25 deletions(-)
 create mode 100644 .patman


base-commit: 025fc600f1cb4c73042bf920aee3e07d5fb9c53a
-- 
2.41.0





^ permalink raw reply	[flat|nested] 28+ messages in thread

* [bug#68680] [PATCH mumi v4 1/4] README.org: Add new sections to help newcomers get started.
  2024-01-26 17:13 ` [bug#68680] [PATCH mumi v4 0/4] Add a button to copy a message " Maxim Cournoyer
@ 2024-01-26 17:13   ` Maxim Cournoyer
  2024-01-26 17:13   ` [bug#68680] [PATCH mumi v4 2/4] .gitignore: Register mumi.xapian and signing-key files Maxim Cournoyer
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 28+ messages in thread
From: Maxim Cournoyer @ 2024-01-26 17:13 UTC (permalink / raw)
  To: 68680; +Cc: rekado, arunisaac, Maxim Cournoyer

* README.org (Running a local instance of mumi): New section.
(Disabling browser caching): Likewise.
---

(no changes since v1)

 README.org | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/README.org b/README.org
index fd1d77b..d092de7 100644
--- a/README.org
+++ b/README.org
@@ -11,3 +11,27 @@ run
 #+BEGIN_SRC shell
   $ guix shell -D mumi
 #+END_SRC
+
+** Running a local instance of mumi
+
+First copy some test mail data to be indexed:
+
+#+begin_src shell
+  $ cp -a tests/data data
+#+end_src
+
+Then, to have these emails indexed, run:
+
+#+begin_src shell
+  $ ./pre-inst-env mumi fetch
+#+end_src
+
+You should now be able to visit http://0.0.0.0:1234 in your browser
+and see your local mumi instance running.
+
+** Disabling browser caching
+
+If you modify the CSS or JavaScript source files, you'll want to make
+sure your browser doesn't keep cached copies.  This can be done by
+changing a preference in the development tools menus, which is called
+something like "Disable cache (while DevTools is active)".
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [bug#68680] [PATCH mumi v4 2/4] .gitignore: Register mumi.xapian and signing-key files.
  2024-01-26 17:13 ` [bug#68680] [PATCH mumi v4 0/4] Add a button to copy a message " Maxim Cournoyer
  2024-01-26 17:13   ` [bug#68680] [PATCH mumi v4 1/4] README.org: Add new sections to help newcomers get started Maxim Cournoyer
@ 2024-01-26 17:13   ` Maxim Cournoyer
  2024-01-26 17:13   ` [bug#68680] [PATCH mumi v4 3/4] Add .patman configuration file Maxim Cournoyer
  2024-01-26 17:13   ` [bug#68680] [PATCH mumi v4 4/4] html: Add a button to copy a Message-ID to the clipboard Maxim Cournoyer
  3 siblings, 0 replies; 28+ messages in thread
From: Maxim Cournoyer @ 2024-01-26 17:13 UTC (permalink / raw)
  To: 68680; +Cc: rekado, arunisaac, Maxim Cournoyer

---

(no changes since v1)

 .gitignore | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.gitignore b/.gitignore
index 2604e48..7247392 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,8 +8,10 @@ config.log
 config.status
 configure
 
+mumi.xapian
 mumi/config.scm
 scripts/mumi
+signing-key
 pre-inst-env
 *.log
 *.trs
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [bug#68680] [PATCH mumi v4 3/4] Add .patman configuration file.
  2024-01-26 17:13 ` [bug#68680] [PATCH mumi v4 0/4] Add a button to copy a message " Maxim Cournoyer
  2024-01-26 17:13   ` [bug#68680] [PATCH mumi v4 1/4] README.org: Add new sections to help newcomers get started Maxim Cournoyer
  2024-01-26 17:13   ` [bug#68680] [PATCH mumi v4 2/4] .gitignore: Register mumi.xapian and signing-key files Maxim Cournoyer
@ 2024-01-26 17:13   ` Maxim Cournoyer
  2024-01-26 17:13   ` [bug#68680] [PATCH mumi v4 4/4] html: Add a button to copy a Message-ID to the clipboard Maxim Cournoyer
  3 siblings, 0 replies; 28+ messages in thread
From: Maxim Cournoyer @ 2024-01-26 17:13 UTC (permalink / raw)
  To: 68680; +Cc: rekado, arunisaac, Maxim Cournoyer

* .patman: New file.
---

(no changes since v1)

 .patman | 7 +++++++
 1 file changed, 7 insertions(+)
 create mode 100644 .patman

diff --git a/.patman b/.patman
new file mode 100644
index 0000000..87b96e9
--- /dev/null
+++ b/.patman
@@ -0,0 +1,7 @@
+[settings]
+project: guix-patches
+patchwork_url: https://patches.guix-patches.cbaines.net
+add_signoff: False
+check_patch: False
+ignore_bad_tags: True
+keep_change_id: True
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [bug#68680] [PATCH mumi v4 4/4] html: Add a button to copy a Message-ID to the clipboard.
  2024-01-26 17:13 ` [bug#68680] [PATCH mumi v4 0/4] Add a button to copy a message " Maxim Cournoyer
                     ` (2 preceding siblings ...)
  2024-01-26 17:13   ` [bug#68680] [PATCH mumi v4 3/4] Add .patman configuration file Maxim Cournoyer
@ 2024-01-26 17:13   ` Maxim Cournoyer
  3 siblings, 0 replies; 28+ messages in thread
From: Maxim Cournoyer @ 2024-01-26 17:13 UTC (permalink / raw)
  To: 68680; +Cc: rekado, arunisaac, Maxim Cournoyer

* mumi/web/view/html.scm (issue-page)
<copy-message-id-button>: New HTML element.
(layout): Bump timestamp on .css and .js files to force reload.
* mumi/web/view/utils.scm (download-icon): Update source.  Use 'rem'
as size unit.
(copy-icon): New variable.
(display-message-body) <download-part>: Add IDs to buttons.  Add to
"message-button" class.
* assets/mumi.scss: Refactor spacing of message header buttons via a
flex display.  Add a shrinking animation to message buttons on hover.
* assets/js/mumi.js (mumi): Register an event for it that copies the
Message-ID to the clipboard.  Add js-indent-level prop line as well as
copyright notices.
* mumi/web/view/html.scm

---

Changes in v4:
 - Set icon sizes via CSS instead of HTML, which improves layout.

Changes in v3:
 - Allow using the new copy button via the keyboard
 - Register event handlers on all copy message-id buttons
 - Move download icon sizes to CSS to resolve warning in Firefox
 - Add guard inside download button event to ensure only one event
   runs at a time, avoiding tooltip getting stuck on 'Copied!'
 - Use a class name instead of a unique ID for the message-id buttons
 - Register handlers to every message-id buttons

Changes in v2:
 - Add timestamp to CSS and JavaScript file names to force reload

 assets/js/mumi.js       | 59 ++++++++++++++++++++++++++++++++++++++++-
 assets/mumi.scss        | 31 +++++++++++++++++++---
 mumi/web/view/html.scm  | 24 ++++++++++++-----
 mumi/web/view/utils.scm | 40 +++++++++++++++++-----------
 4 files changed, 129 insertions(+), 25 deletions(-)

diff --git a/assets/js/mumi.js b/assets/js/mumi.js
index ab29f08..77b9276 100644
--- a/assets/js/mumi.js
+++ b/assets/js/mumi.js
@@ -1,4 +1,8 @@
-// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3.0-or-later
+// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3.0-or-later  -*- js-indent-level: 2; -*-
+//
+// Copyright © 2019, 2022, 2023 Ricardo Wurmus <rekado@elephly.net>
+// Copyright © 2024 Maxim Cournoyer <maxim.cournoyer@gmail.com>
+//
 var mumi = (function () {
   const possibleTokens = [
     { text: 'is:open' },
@@ -129,12 +133,65 @@ var mumi = (function () {
   var init = function () {
     initTokenInput ();
   };
+
+  // Copy a message Message-ID to the clipboard.
+  var setupMessageIdButtonHandler = () => {
+
+    // Avoid having the async timeout code starting while a previous
+    // one is ongoing, which would corrupt the tooltip text.
+    var isMessageIdHandlerRunning = false;
+
+    let messageIdHandler = (evt) => {
+      if (isMessageIdHandlerRunning) return;
+      isMessageIdHandlerRunning = true;
+
+      // If the button was triggered by a keyup event, check if it was
+      // the Enter key.
+      if (evt.type === "keyup" && event.key !== "Enter") return;
+
+      messageIdButton = evt.currentTarget;
+      originalTooltip = messageIdButton.dataset.tooltip;
+      var messageId = messageIdButton.dataset.messageId;
+      if (!window.isSecureContext) {
+	console.log("not in a secure context -- " +
+		    "cannot copy message-id to clipboard\n" +
+		    "tip: for testing, open via http://localhost:1234");
+	return;
+      }
+
+      // Avoid the button being stuck in the focused state when a
+      // mouse is used, to avoid UI clutter.
+      if (evt.type === "click") {
+	messageIdButton.removeAttribute('tabindex');
+      }
+
+      // Update button's tooltip for the next 3 s.
+      messageIdButton.dataset.tooltip = "Copied!";
+      setTimeout(() => {
+	messageIdButton.dataset.tooltip = originalTooltip;
+	if (evt.type === "click") {
+	  // Re-add the tabindex attribute.
+	  messageIdButton.setAttribute("tabindex", "0")
+	  isMessageIdHandlerRunning = false;
+	}}, 3000);
+
+      navigator.clipboard.writeText(messageId);
+      console.log("copied Message-ID " + messageId + " to clipboard");
+    };
+
+    document.querySelectorAll(".copy-message-id-button").forEach((btn) => {
+      btn.addEventListener("click", messageIdHandler);
+      btn.addEventListener("keyup", messageIdHandler)});
+  };
+
   return({
     'init': init,
     'lines': setupLineHandler,
+    'messageIdButtonHandler': setupMessageIdButtonHandler,
   });
 })();
 
 window.addEventListener ("load", mumi.init);
 window.addEventListener ("DOMContentLoaded", mumi.lines);
+window.addEventListener ("DOMContentLoaded", mumi.messageIdButtonHandler);
 // @license-end
diff --git a/assets/mumi.scss b/assets/mumi.scss
index 822f110..e605630 100644
--- a/assets/mumi.scss
+++ b/assets/mumi.scss
@@ -506,11 +506,36 @@ details {
     margin-right: 0.2em;
 }
 
-.download-message,
 .download-part {
     float: right;
-    font-size: 0.8em;
-    font-style: italic;
+}
+
+.header-buttons {
+    display: flex;
+    flex-direction: row;
+    float: right;
+    justify-content: flex-end;
+ }
+
+.header-buttons > * {
+    margin: 0 0 0 0.5rem;
+    // Custom buttons: undo the Pico CSS default style.  We use
+    // buttons for inheriting their CSS style when focused via the
+    // keyboard.
+    background: revert;
+    border: revert;
+    color: revert;
+    padding: revert;
+}
+
+.bi-copy,
+.bi-download{
+    height: 1rem;
+    width: 1rem;
+}
+
+.message-button:hover {
+    transform: scale(0.95);
 }
 
 @media (min-width: 768px) {
diff --git a/mumi/web/view/html.scm b/mumi/web/view/html.scm
index 8f06a36..104162d 100644
--- a/mumi/web/view/html.scm
+++ b/mumi/web/view/html.scm
@@ -1,6 +1,7 @@
 ;;; mumi -- Mediocre, uh, mail interface
 ;;; Copyright © 2016, 2017, 2018, 2019, 2020, 2021, 2022 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2018, 2019, 2023 Arun Isaac <arunisaac@systemreboot.net>
+;;; Copyright © 2024 Maxim Cournoyer <maxim.cournoyer@gmail.com>
 ;;;
 ;;; This program is free software: you can redistribute it and/or
 ;;; modify it under the terms of the GNU Affero General Public License
@@ -62,11 +63,11 @@
        (@ (rel "stylesheet")
           (media "screen")
           (type "text/css")
-          (href "/css/mumi.css?20221231000000")))
+          (href "/css/mumi.css?20240126000000")))
       (script
        (@ (src "/js/tokeninput.js")))
       (script
-       (@ (src "/js/mumi.js")))
+       (@ (src "/js/mumi.js?20240126000000")))
       ,@head)
      (body (script
             (@ (src "/js/theme-switcher.js")))
@@ -612,6 +613,7 @@ currently disabled."))
                 (not (bug-archived bug)))
            mailer-form
            disabled-mailer)))
+
   (define (show-message message-number message previous-subject)
     `((div
        (a (@ (class "message-anchor")
@@ -642,10 +644,20 @@ currently disabled."))
                                                  message-number)))
                       (title ,(date->string (date message))))
                    ,(time->string (date message)))))
-         (div (@ (class "download-message"))
-              (a (@ (href ,(format #f "/issue/~a/raw/~a"
-                                   id message-number)))
-                 ,download-icon))
+         (div (@ (class "header-buttons"))
+              (div (@ (class "copy-message-id-button message-button")
+                      (tabindex "0")    ;make it keyboard-usable
+                      (role "button")   ;specific to Pico CSS
+                      (data-tooltip "Copy Message-ID")
+                      (data-message-id ,(message-id message)))
+                   ,copy-icon)
+              (div (@ (id "download-raw-message-button")
+                      (class "message-button")
+                      (role "button")
+                      (data-tooltip "Download raw message"))
+                   (a (@ (href ,(format #f "/issue/~a/raw/~a"
+                                        id message-number)))
+                      ,download-icon)))
          ,@(if (string-suffix? previous-subject (subject message))
                '()
                `((div (@ (class "subject")) ,(subject message))))
diff --git a/mumi/web/view/utils.scm b/mumi/web/view/utils.scm
index 1ce7b64..712d198 100644
--- a/mumi/web/view/utils.scm
+++ b/mumi/web/view/utils.scm
@@ -2,6 +2,7 @@
 ;;; Copyright © 2017, 2018, 2019, 2020 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2018, 2019 Arun Isaac <arunisaac@systemreboot.net>
 ;;; Copyright © 2018 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2024 Maxim Cournoyer <maxim.cournoyer@gmail.com>
 ;;;
 ;;; This program is free software: you can redistribute it and/or
 ;;; modify it under the terms of the GNU Affero General Public License
@@ -35,6 +36,7 @@
   #:use-module (web uri)
   #:export (prettify
             avatar-color
+            copy-icon
             download-icon
             display-message-body
             time->string))
@@ -215,23 +217,27 @@ numbers with the given MESSAGE-NUMBER."
 ;; https://icons.getbootstrap.com/icons/download/
 (define download-icon
   '(svg (@ (class "bi bi-download")
-           (width "1em")
-           (height "1em")
            (viewBox "0 0 16 16")
            (fill "currentColor")
            (xmlns "http://www.w3.org/2000/svg"))
-        (title "Download")
-        (path (@ (fill-rule "evenodd")
-                 (clip-rule "evenodd")
-                 (d "M.5 8a.5.5 0 01.5.5V12a1 1 0 001 1h12a1 1 0 001-1\
-V8.5a.5.5 0 011 0V12a2 2 0 01-2 2H2a2 2 0 01-2-2V8.5A.5.5 0 01.5 8z")) "")
-        (path (@ (fill-rule "evenodd")
-                 (clip-rule "evenodd")
-                 (d "M5 7.5a.5.5 0 01.707 0L8 9.793 10.293 7.5a.5.5 0 \
-11.707.707l-2.646 2.647a.5.5 0 01-.708 0L5 8.207A.5.5 0 015 7.5z")) "")
+        (path (@ (d "M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 \
+1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 \
+1-2-2v-2.5a.5.5 0 0 1 .5-.5")))
+        (path (@ (d "M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 \
+0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 \
+1 0-.708.708z")))))
+
+;; https://icons.getbootstrap.com/icons/copy/
+(define copy-icon
+  '(svg (@ (class "bi bi-copy")
+           (viewBox "0 0 16 16")
+           (fill "currentColor")
+           (xmlns "http://www.w3.org/2000/svg"))
         (path (@ (fill-rule "evenodd")
-                 (clip-rule "evenodd")
-                 (d "M8 1a.5.5 0 01.5.5v8a.5.5 0 01-1 0v-8A.5.5 0 018 1z")) "")))
+                 (d "M4 2a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H6a2 \
+2 0 0 1-2-2zm2-1a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V2a1 1 0 0 \
+0-1-1zM2 5a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1v-1h1v1a2 2 0 0 1-2 \
+2H2a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h1v1z")))))
 
 (define* (display-message-body bug-num message-number message #:optional plain?)
   "Convenience procedure to render MESSAGE (part of bug with number
@@ -285,7 +291,9 @@ lines when PLAIN? is #T."
                    "")))
        ((string-suffix? ".scm" attachment-name)
         `(div (@ (class "multipart scheme"))
-              (div (@ (class "download-part"))
+              (div (@ (id "download-scheme-part-button")
+                      (class "download-part message-button")
+                      (data-tooltip "Download Scheme file"))
                    (a (@ (href ,(attachment-url)))
                       ,download-icon))
               ,(highlights->sxml (highlight lex-scheme body))))
@@ -294,7 +302,9 @@ lines when PLAIN? is #T."
                           (list "multipart" (or (and content-type
                                                      (content-type->css-class content-type))
                                                 "")))))
-              (div (@ (class "download-part"))
+              (div (@ (id "download-part-button")
+                      (class "download-part message-button")
+                      (data-tooltip "Download MIME part"))
                    (a (@ (href ,(attachment-url)))
                       ,download-icon))
               ,(cond
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [bug#68680] [PATCH mumi v2 1/3] README.org: Add new sections to help newcomers get started.
  2024-01-25 17:00   ` [bug#68680] [PATCH mumi v2 1/3] README.org: Add new sections to help newcomers get started Maxim Cournoyer
@ 2024-01-26 21:18     ` Arun Isaac
  2024-01-27  3:55       ` Maxim Cournoyer
  0 siblings, 1 reply; 28+ messages in thread
From: Arun Isaac @ 2024-01-26 21:18 UTC (permalink / raw)
  To: Maxim Cournoyer, 68680; +Cc: rekado


> +You should now be able to visit http://0.0.0.0:1234 in your browser
> +and see your local mumi instance running.

Could you also mention just before this paragraph, the `mumi web'
command that starts the web server?




^ permalink raw reply	[flat|nested] 28+ messages in thread

* [bug#68680] [PATCH mumi v2 0/3] Add a button to copy a message Message-ID to the clipboard.
  2024-01-25 17:00 ` [bug#68680] [PATCH mumi v2 " Maxim Cournoyer
                     ` (2 preceding siblings ...)
  2024-01-25 17:00   ` [bug#68680] [PATCH mumi v2 3/3] html: Add a button to copy a Message-ID to the clipboard Maxim Cournoyer
@ 2024-01-26 21:21   ` Arun Isaac
  2024-01-26 21:24     ` Arun Isaac
  2024-01-27  3:04     ` [bug#68680] " Maxim Cournoyer
  3 siblings, 2 replies; 28+ messages in thread
From: Arun Isaac @ 2024-01-26 21:21 UTC (permalink / raw)
  To: Maxim Cournoyer, 68680; +Cc: rekado


> Changes in v2:
>  - Add timestamp to CSS and JavaScript file names to force reload

Do we need to have timestamps on the CSS and JS filenames? If we
configured nginx to serve these static files, wouldn't caching and
reloading be handled automatically via the ETag or Last-Modified
headers?




^ permalink raw reply	[flat|nested] 28+ messages in thread

* [bug#68680] [PATCH mumi v2 0/3] Add a button to copy a message Message-ID to the clipboard.
  2024-01-26 21:21   ` [bug#68680] [PATCH mumi v2 0/3] Add a button to copy a message " Arun Isaac
@ 2024-01-26 21:24     ` Arun Isaac
  2024-01-27  3:57       ` bug#68680: " Maxim Cournoyer
  2024-01-27  3:04     ` [bug#68680] " Maxim Cournoyer
  1 sibling, 1 reply; 28+ messages in thread
From: Arun Isaac @ 2024-01-26 21:24 UTC (permalink / raw)
  To: Maxim Cournoyer, 68680; +Cc: rekado


Looks good to me otherwise. The patch running on berlin actually
works. So, all is well, I guess!




^ permalink raw reply	[flat|nested] 28+ messages in thread

* [bug#68680] [PATCH mumi v2 0/3] Add a button to copy a message Message-ID to the clipboard.
  2024-01-26 21:21   ` [bug#68680] [PATCH mumi v2 0/3] Add a button to copy a message " Arun Isaac
  2024-01-26 21:24     ` Arun Isaac
@ 2024-01-27  3:04     ` Maxim Cournoyer
  2024-01-27 10:06       ` Arun Isaac
  1 sibling, 1 reply; 28+ messages in thread
From: Maxim Cournoyer @ 2024-01-27  3:04 UTC (permalink / raw)
  To: Arun Isaac; +Cc: rekado, 68680

Hi,

Arun Isaac <arunisaac@systemreboot.net> writes:

>> Changes in v2:
>>  - Add timestamp to CSS and JavaScript file names to force reload
>
> Do we need to have timestamps on the CSS and JS filenames? If we
> configured nginx to serve these static files, wouldn't caching and
> reloading be handled automatically via the ETag or Last-Modified
> headers?

I haven't looked at our nginx configuration, but currently the js and
css files were not reloaded without this hack, no.

-- 
Thanks,
Maxim




^ permalink raw reply	[flat|nested] 28+ messages in thread

* [bug#68680] [PATCH mumi v2 1/3] README.org: Add new sections to help newcomers get started.
  2024-01-26 21:18     ` Arun Isaac
@ 2024-01-27  3:55       ` Maxim Cournoyer
  0 siblings, 0 replies; 28+ messages in thread
From: Maxim Cournoyer @ 2024-01-27  3:55 UTC (permalink / raw)
  To: Arun Isaac; +Cc: rekado, 68680

Hi,

Arun Isaac <arunisaac@systemreboot.net> writes:

>> +You should now be able to visit http://0.0.0.0:1234 in your browser
>> +and see your local mumi instance running.
>
> Could you also mention just before this paragraph, the `mumi web'
> command that starts the web server?

Done.

-- 
Thanks,
Maxim




^ permalink raw reply	[flat|nested] 28+ messages in thread

* bug#68680: [PATCH mumi v2 0/3] Add a button to copy a message Message-ID to the clipboard.
  2024-01-26 21:24     ` Arun Isaac
@ 2024-01-27  3:57       ` Maxim Cournoyer
  0 siblings, 0 replies; 28+ messages in thread
From: Maxim Cournoyer @ 2024-01-27  3:57 UTC (permalink / raw)
  To: Arun Isaac; +Cc: rekado, 68680-done

Hi Arun,

Arun Isaac <arunisaac@systemreboot.net> writes:

> Looks good to me otherwise. The patch running on berlin actually
> works. So, all is well, I guess!

Great!  I'll bump mumi's version to 0.0.6 and update the package in
Guix.

-- 
Thanks,
Maxim




^ permalink raw reply	[flat|nested] 28+ messages in thread

* [bug#68680] [PATCH mumi v2 0/3] Add a button to copy a message Message-ID to the clipboard.
  2024-01-27  3:04     ` [bug#68680] " Maxim Cournoyer
@ 2024-01-27 10:06       ` Arun Isaac
  2024-01-27 12:20         ` Ricardo Wurmus
  0 siblings, 1 reply; 28+ messages in thread
From: Arun Isaac @ 2024-01-27 10:06 UTC (permalink / raw)
  To: Maxim Cournoyer; +Cc: rekado, 68680


> I haven't looked at our nginx configuration, but currently the js and
> css files were not reloaded without this hack, no.

Ok, maybe for another time, then. But, we should handle this kind of
thing in the nginx configuration of the mumi service.

Thank you for the patchset. Much appreciated! :-)




^ permalink raw reply	[flat|nested] 28+ messages in thread

* [bug#68680] [PATCH mumi v2 0/3] Add a button to copy a message Message-ID to the clipboard.
  2024-01-27 10:06       ` Arun Isaac
@ 2024-01-27 12:20         ` Ricardo Wurmus
  2024-01-29 23:41           ` Arun Isaac
  0 siblings, 1 reply; 28+ messages in thread
From: Ricardo Wurmus @ 2024-01-27 12:20 UTC (permalink / raw)
  To: Arun Isaac; +Cc: Maxim Cournoyer, 68680


Arun Isaac <arunisaac@systemreboot.net> writes:

>> I haven't looked at our nginx configuration, but currently the js and
>> css files were not reloaded without this hack, no.
>
> Ok, maybe for another time, then. But, we should handle this kind of
> thing in the nginx configuration of the mumi service.

I think we used to have (and maybe still have) a problem with caching
files that are served from the store with a zero timestamp.

-- 
Ricardo




^ permalink raw reply	[flat|nested] 28+ messages in thread

* [bug#68680] [PATCH mumi v2 0/3] Add a button to copy a message Message-ID to the clipboard.
  2024-01-27 12:20         ` Ricardo Wurmus
@ 2024-01-29 23:41           ` Arun Isaac
  0 siblings, 0 replies; 28+ messages in thread
From: Arun Isaac @ 2024-01-29 23:41 UTC (permalink / raw)
  To: Ricardo Wurmus; +Cc: Maxim Cournoyer, 68680


> I think we used to have (and maybe still have) a problem with caching
> files that are served from the store with a zero timestamp.

Oh my, I forgot about the store. That's a bummer. We should workaround
this[1] with some other non-timestamp based caching strategy. Perhaps we
can set a max-age using the Cache-Control
header. https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#fresh_and_stale_based_on_age

[1]: later, and not part of this issue




^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2024-01-29 23:42 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-01-24  2:15 [bug#68680] [PATCH mumi 0/3] Add a button to copy a message Message-ID to the clipboard Maxim Cournoyer
2024-01-24  2:20 ` [bug#68680] [PATCH mumi 1/3] README.org: Add new sections to help newcomers get started Maxim Cournoyer
2024-01-24  2:20   ` [bug#68680] [PATCH mumi 2/3] .gitignore: Register mumi.xapian and signing-key files Maxim Cournoyer
2024-01-24  2:20   ` [bug#68680] [PATCH mumi 3/3] html: Add a button to copy a Message-ID to the clipboard Maxim Cournoyer
2024-01-24  2:29 ` [bug#68680] [PATCH mumi 0/3] Add a button to copy a message " Maxim Cournoyer
2024-01-25 17:00 ` [bug#68680] [PATCH mumi v2 " Maxim Cournoyer
2024-01-25 17:00   ` [bug#68680] [PATCH mumi v2 1/3] README.org: Add new sections to help newcomers get started Maxim Cournoyer
2024-01-26 21:18     ` Arun Isaac
2024-01-27  3:55       ` Maxim Cournoyer
2024-01-25 17:00   ` [bug#68680] [PATCH mumi v2 2/3] .gitignore: Register mumi.xapian and signing-key files Maxim Cournoyer
2024-01-25 17:00   ` [bug#68680] [PATCH mumi v2 3/3] html: Add a button to copy a Message-ID to the clipboard Maxim Cournoyer
2024-01-26 21:21   ` [bug#68680] [PATCH mumi v2 0/3] Add a button to copy a message " Arun Isaac
2024-01-26 21:24     ` Arun Isaac
2024-01-27  3:57       ` bug#68680: " Maxim Cournoyer
2024-01-27  3:04     ` [bug#68680] " Maxim Cournoyer
2024-01-27 10:06       ` Arun Isaac
2024-01-27 12:20         ` Ricardo Wurmus
2024-01-29 23:41           ` Arun Isaac
2024-01-26  2:26 ` [bug#68680] [PATCH mumi v3 0/4] " Maxim Cournoyer
2024-01-26  2:26   ` [bug#68680] [PATCH mumi v3 1/4] README.org: Add new sections to help newcomers get started Maxim Cournoyer
2024-01-26  2:26   ` [bug#68680] [PATCH mumi v3 2/4] .gitignore: Register mumi.xapian and signing-key files Maxim Cournoyer
2024-01-26  2:26   ` [bug#68680] [PATCH mumi v3 3/4] Add .patman configuration file Maxim Cournoyer
2024-01-26  2:26   ` [bug#68680] [PATCH mumi v3 4/4] html: Add a button to copy a Message-ID to the clipboard Maxim Cournoyer
2024-01-26 17:13 ` [bug#68680] [PATCH mumi v4 0/4] Add a button to copy a message " Maxim Cournoyer
2024-01-26 17:13   ` [bug#68680] [PATCH mumi v4 1/4] README.org: Add new sections to help newcomers get started Maxim Cournoyer
2024-01-26 17:13   ` [bug#68680] [PATCH mumi v4 2/4] .gitignore: Register mumi.xapian and signing-key files Maxim Cournoyer
2024-01-26 17:13   ` [bug#68680] [PATCH mumi v4 3/4] Add .patman configuration file Maxim Cournoyer
2024-01-26 17:13   ` [bug#68680] [PATCH mumi v4 4/4] html: Add a button to copy a Message-ID to the clipboard Maxim Cournoyer

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/guix.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.