branch: elpa/mastodon
commit f6247f0c9b8c15b19e8ddca2f600ceb2cf48beb9
Merge: 163ba2b0b8 e24f6ee5db
Author: marty hiatt <martianhia...@disroot.org>
Commit: marty hiatt <martianhia...@disroot.org>

    Merge branch 'develop'
---
 README.org                |  11 +--
 lisp/mastodon-http.el     |   7 +-
 lisp/mastodon-profile.el  |   3 +-
 lisp/mastodon-tl.el       | 172 ++++++++++++++++++++++++++++++++++++++--------
 lisp/mastodon-toot.el     |   7 +-
 lisp/mastodon.el          |  11 ++-
 test/mastodon-tl-tests.el |  47 +++++++++++++
 7 files changed, 213 insertions(+), 45 deletions(-)

diff --git a/README.org b/README.org
index 1b80e59c3d..caf9b0e629 100644
--- a/README.org
+++ b/README.org
@@ -565,11 +565,12 @@ am=, if you want to actually contribute a commit.
 
 *** Fixes and features
 
-1. Create an [[https://codeberg.org/martianh/mastodon.el/issues][issue]] 
detailing what you'd like to do.
-2. Fork the repository and create a branch off of =develop=.
-3. Run the tests and ensure that your code doesn't break any of them.
-4. Create a pull request (to develop) referencing the issue created in
-   step 1.
+1. Install 
[[https://cask.readthedocs.io/en/latest/guide/installation.html][Cask]] if you 
don't already have it installed
+2. Create an [[https://codeberg.org/martianh/mastodon.el/issues][issue]] 
detailing what you'd like to do.
+3. Fork the repository and create a branch off of =develop=.
+4. Run the tests (with =make tests=) and ensure that your code doesn't break 
any of them.
+5. Create a pull request (to develop) referencing the issue created in
+   step 2.
 
 *** Coding style
 
diff --git a/lisp/mastodon-http.el b/lisp/mastodon-http.el
index a55097dff2..a91f272dd4 100644
--- a/lisp/mastodon-http.el
+++ b/lisp/mastodon-http.el
@@ -220,9 +220,10 @@ Callback to `mastodon-http--get-response-async', usually
     (goto-char (point-min))
     (re-search-forward "^$" nil 'move)
     (let ((json-array-type (if vector 'vector 'list))
-          (json-string (decode-coding-string
-                        (buffer-substring-no-properties (point) (point-max))
-                        'utf-8)))
+          (json-string (string-trim-right
+                        (decode-coding-string
+                         (buffer-substring-no-properties (point) (point-max))
+                         'utf-8))))
       (kill-buffer)
       (cond ((or (string-empty-p json-string) (null json-string))
              nil)
diff --git a/lisp/mastodon-profile.el b/lisp/mastodon-profile.el
index 95d275d253..177179fdf1 100644
--- a/lisp/mastodon-profile.el
+++ b/lisp/mastodon-profile.el
@@ -693,7 +693,8 @@ MAX-ID is a flag to include the max_id pagination 
parameter."
              (mastodon-profile--image-from-account account 'avatar_static)
              (mastodon-profile--image-from-account account 'header_static)
              "\n"
-             (propertize .display_name 'face 'mastodon-display-name-face)
+             (when .display_name
+               (propertize .display_name 'face 'mastodon-display-name-face))
              ;; roles
              (when .roles
                (concat " " (mastodon-profile--render-roles .roles)))
diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el
index 508332b098..b1a5b90cdd 100644
--- a/lisp/mastodon-tl.el
+++ b/lisp/mastodon-tl.el
@@ -95,6 +95,9 @@
 (autoload 'mastodon-notifications--current-type "mastodon-notifications")
 (autoload 'mastodon-notifications--timeline "mastodon-notifications")
 (autoload 'mastodon-notifications--empty-group-json-p "mastodon-notifications")
+(autoload 'mastodon-search--print-tags "mastodon-search")
+(autoload 'mastodon-profile-show-user "mastodon-profile")
+
 (defvar mastodon-toot--visibility)
 (defvar mastodon-toot-mode)
 (defvar mastodon-active-user)
@@ -508,8 +511,8 @@ MAX-ID is a flag to add the max_id pagination parameter."
   (interactive "p")
   (let* ((params
           `(("limit" . ,mastodon-tl--timeline-posts-count)
-            ,(when max-id
-               `("max_id" . ,(mastodon-tl--buffer-property 'max-id))))))
+            ,@(when max-id
+                `(("max_id" . ,(mastodon-tl--buffer-property 'max-id)))))))
     (message "Loading home timeline...")
     (mastodon-tl--init "home" "timelines/home" 'mastodon-tl--timeline nil
                        params
@@ -637,7 +640,8 @@ is extracted from it."
   (let ((data (or (alist-get 'account toot)
                   toot))) ;; grouped nofifs use account data directly
     (let-alist data
-      (propertize (if (not (string-empty-p .display_name))
+      (propertize (if (and .display_name
+                           (not (string-empty-p .display_name)))
                       .display_name
                     .username)
                   'face 'mastodon-display-name-face
@@ -1164,6 +1168,39 @@ the toot)."
                (string-prefix-p "/tag" path)) ;; "/tag/" or "/tags/"
       (nth 2 split))))
 
+(defun mastodon-tl--base-tags (tags body-tags)
+  "Return a string of all tags not in BODY-TAGS, linkified.
+TAGS is a list of tag alists, from a post's JSON."
+  (when (mastodon-tl--base-tags-print-p tags body-tags)
+    (concat
+     "\n"
+     (cl-loop for tag in tags
+              concat (concat (mastodon-tl--render-base-tag tag body-tags)
+                             " ")))))
+
+(defun mastodon-tl--base-tags-print-p (tags body-tags)
+  "Non-nil if we need to print base tags.
+We need to do so if TAGS contains any elements not in BODY-TAGS."
+  (cl-remove-if (lambda (tag)
+                  (member (alist-get 'name tag) body-tags))
+                tags))
+
+(defun mastodon-tl--render-base-tag (tag body-tags)
+  "Return TAG as a linkified string, provided it is not in BODY-TAGS."
+  (let ((name (alist-get 'name tag)))
+    (unless (member (downcase name) body-tags)
+      (mastodon-tl--buttonify-link
+       (concat "#" name)
+       'mastodon-tab-stop 'hashtag
+       'mastodon-tag name
+       'mouse-face '(highlight)
+       'keymap mastodon-tl--link-keymap
+       'face '(shr-text shr-link)
+       'follow-link t
+       'shr-tab-stop t
+       'shr-url (alist-get 'url tag)
+       'help-echo (concat "Browse tag #" name)))))
+
 
 ;;; HYPERLINKS
 
@@ -1796,6 +1833,25 @@ Runs `mastodon-tl--render-text' and fetches poll or 
media."
   (let ((prev-id (mastodon-tl--prev-item-id)))
     (string= reply-to-id prev-id)))
 
+(defun mastodon-tl--body-tags (body)
+  "Return a plain string list of the tags in BODY."
+  ;; NB: replies on text props 'mastodon-tab-stop and 'shr-url
+  ;; FIXME: snac tags fail our prop test, not sure about others.
+  (let (list prop)
+    (with-temp-buffer
+      (insert body)
+      (goto-char (point-min))
+      (save-match-data
+        (while
+            (setq prop (text-property-search-forward
+                        'mastodon-tab-stop 'hashtag t))
+          (goto-char (prop-match-beginning prop))
+          (let ((tag (mastodon-tl--property 'mastodon-tag)))
+            (when tag
+              (push (downcase tag) list)))
+          (goto-char (prop-match-end prop)))))
+    list))
+
 (defun mastodon-tl--insert-status
     (toot body &optional detailed-p thread domain unfolded no-byline
           cw-expanded)
@@ -1818,7 +1874,8 @@ CW-EXPANDED means treat content warnings as unfolded."
                (length> body mastodon-tl--fold-toots-at-length)))
          (cw-p (not
                 (string-empty-p
-                 (alist-get 'spoiler_text toot)))))
+                 (alist-get 'spoiler_text toot))))
+         (body-tags (mastodon-tl--body-tags body)))
     (insert
      (propertize ;; body + byline:
       (concat
@@ -1845,6 +1902,11 @@ CW-EXPANDED means treat content warnings as unfolded."
               "LESS" cw-p (not cw-expanded))
            ""))
         'toot-body t) ;; includes newlines etc. for folding
+       ;; post tags:
+       (let ((tags (alist-get 'tags toot)))
+         ;; FIXME: we also need to test here for normal body tags, and if
+         ;; so, don't go ahead:
+         (if tags (concat (mastodon-tl--base-tags tags body-tags)) ""))
        ;; byline:
        "\n"
        (if no-byline
@@ -2281,7 +2343,10 @@ call this function after it is set or use something 
else."
           ((mastodon-tl--endpoint-str-= "timelines/link")
            'link-timeline)
           ((mastodon-tl--endpoint-str-= "announcements")
-           'announcements))))
+           'announcements)
+          ;; followed hashtags
+          ((mastodon-tl--endpoint-str-= "followed_tags")
+           'followed-hashtags))))
 
 (defun mastodon-tl--buffer-type-eq (type)
   "Return t if current buffer type is equal to symbol TYPE."
@@ -2322,7 +2387,8 @@ We hide replies if user explictly set the
 `mastodon-tl--hide-replies' or used PREFIX combination to open a
 timeline."
   (and (mastodon-tl--timeline-proper-p) ; Only if we are in a proper timeline
-       (or mastodon-tl--hide-replies ; User configured to hide replies
+       (or (mastodon-tl--buffer-property 'hide-replies nil :noerror)
+           mastodon-tl--hide-replies ; User configured to hide replies
            (equal '(4) prefix)))) ; Timeline called with C-u prefix
 
 
@@ -2443,10 +2509,15 @@ webapp"
 
 ;;; THREADS
 
-(defun mastodon-tl-single-toot (id)
-  "View toot at point in separate buffer.
-ID is that of the toot to view."
+(defun mastodon-tl-view-single-toot ()
+  "View toot at point in a separate buffer."
   (interactive)
+  (let ((id (mastodon-tl--property 'base-item-id)))
+    (mastodon-tl--single-toot id)))
+
+(defun mastodon-tl--single-toot (id)
+  "View toot in separate buffer.
+ID is that of the toot to view."
   (let* ((buffer (format "*mastodon-toot-%s*" id))
          (toot (mastodon-http--get-json
                 (mastodon-http--api (concat "statuses/" id)))))
@@ -2467,7 +2538,7 @@ ID is that of the toot to view."
 (defun mastodon-tl--update-toot (json)
   "Call `mastodon-tl-single-toot' on id found in JSON."
   (let ((id (alist-get 'id json)))
-    (mastodon-tl-single-toot id)))
+    (mastodon-tl--single-toot id)))
 
 (defun mastodon-tl-view-whole-thread ()
   "From a thread view, view entire thread.
@@ -2481,6 +2552,19 @@ view all branches of a thread."
     (let ((id (mastodon-tl--property 'base-item-id)))
       (mastodon-tl--thread-do id))))
 
+(defun mastodon-tl-return ()
+  "Load user profile or thread of item at point.
+If item at point is a follow or follow request, load user profile.
+Else load thread."
+  (interactive)
+  (let ((notif (mastodon-tl--property 'notification-type)))
+    (if (or (equal "follow" notif)
+            (equal "follow_request" notif))
+        (let* ((json (mastodon-tl--property 'item-json))
+               (handle (alist-get 'acct json)))
+          (mastodon-profile-show-user handle))
+      (mastodon-tl-thread))))
+
 (defun mastodon-tl-thread ()
   "Open thread buffer for toot at point."
   (interactive)
@@ -2493,12 +2577,16 @@ view all branches of a thread."
 This is the non-interactive version, so we can call it
 programmatically and not crash into
 `mastodon-toot--with-toot-item'."
-  ;; this function's var must not be id as the above macro binds id and even
-  ;; if we provide the arg (e.g. url-lookup), the macro definition overrides
-  ;; it, making the optional arg unusable!
+  ;; this function's var must not be id as the above macro binds id and
+  ;; even if we provide the arg (e.g. url-lookup), the macro definition
+  ;; overrides it, making the optional arg unusable!
   (let* ((id (or thread-id (mastodon-tl--property 'base-item-id :no-move)))
-         (type (mastodon-tl--field 'type
-                                   (mastodon-tl--property 'item-json 
:no-move)))
+         (type
+          (if (and (mastodon-tl--buffer-type-eq 'notifications)
+                   mastodon-group-notifications)
+              (mastodon-tl--property 'notification-type)
+            (mastodon-tl--field 'type
+                                (mastodon-tl--property 'item-json :no-move))))
          (unfolded-state (mastodon-tl--buffer-property 'thread-unfolded
                                                        (current-buffer) 
:noerror))
          (mastodon-tl--expand-content-warnings
@@ -2524,7 +2612,7 @@ programmatically and not crash into
           (if (not (< 0 (+ (length (alist-get 'ancestors context))
                            (length (alist-get 'descendants context)))))
               ;; just print the lone toot:
-              (mastodon-tl-single-toot id)
+              (mastodon-tl--single-toot id)
             ;; we have a thread:
             (with-mastodon-buffer buffer #'mastodon-mode nil
               (let ((marker (make-marker)))
@@ -2988,8 +3076,8 @@ If TAG is provided, unfollow it."
                            (lambda (_)
                              (message "tag #%s unfollowed!" tag)))))
 
-(defun mastodon-tl-list-followed-tags (&optional prefix)
-  "List followed tags. View timeline of tag user choses.
+(defun mastodon-tl-jump-to-followed-tag (&optional prefix)
+  "Prompt for a followed tag and view its timeline.
 PREFIX is sent to `mastodon-tl-get-tag-timeline', which see."
   (interactive "p")
   (let* ((followed-tags-json (mastodon-tl--followed-tags))
@@ -2999,6 +3087,25 @@ PREFIX is sent to `mastodon-tl-get-tag-timeline', which 
see."
         (user-error "You have to follow some tags first")
       (mastodon-tl-get-tag-timeline prefix tag))))
 
+(defun mastodon-tl-list-followed-tags ()
+  "List followed tags. View timeline of tag user choses.
+PREFIX is sent to `mastodon-tl-get-tag-timeline', which see."
+  (interactive)
+  (let* ((json (mastodon-tl--followed-tags))
+         (sorted (sort json :key (lambda (x)
+                                   (downcase (alist-get 'name x)))))
+         (buf "*mastodon-followed-tags*"))
+    (if (null sorted)
+        (user-error "You have to follow some tags first")
+      (with-mastodon-buffer (get-buffer-create buf)
+          #'mastodon-mode nil
+        (mastodon-tl--set-buffer-spec
+         buf "followed_tags" #'mastodon-tl-list-followed-tags)
+        (mastodon-search--insert-heading "followed tags")
+        (insert "\n")
+        (mastodon-search--print-tags sorted)
+        (goto-char (point-min))))))
+
 (defun mastodon-tl-followed-tags-timeline (&optional prefix)
   "Open a timeline of multiple tags.
 With a single PREFIX arg, only show posts with media.
@@ -3279,20 +3386,22 @@ and profile pages when showing followers or accounts 
followed."
             (mastodon-tl--update-params)
             'mastodon-tl--more* (current-buffer) (point)))
           (t ;; max_id paginate (timelines, items with ids/timestamps):
-           (let ((max-id (mastodon-tl--oldest-id)))
+           (let ((max-id (mastodon-tl--oldest-id))
+                 (params (mastodon-tl--update-params)))
              (mastodon-tl--more-json-async
               (mastodon-tl--endpoint)
-              max-id
-              (mastodon-tl--update-params)
-              'mastodon-tl--more* (current-buffer) (point) nil max-id))))))
+              max-id params
+              'mastodon-tl--more*
+              (current-buffer) (point) nil max-id))))))
 
-(defun mastodon-tl--more* (response buffer point-before
-                                    &optional headers max-id)
+(defun mastodon-tl--more*
+    (response buffer point-before &optional headers max-id)
   "Append older toots to timeline, asynchronously.
 Runs the timeline's update function on RESPONSE, in BUFFER.
 When done, places point at POINT-BEFORE.
 HEADERS is the http headers returned in the response, if any.
-MAX-ID is the pagination parameter, a string."
+MAX-ID is the pagination parameter, a string.
+UPDATE-PARAMS is from prev buffer spec, added to the new one."
   (with-current-buffer buffer
     (if (not response)
         (user-error "No more results")
@@ -3335,10 +3444,12 @@ MAX-ID is the pagination parameter, a string."
             (goto-char point-before)
             ;; update buffer spec to new link-header or max-id:
             ;; (other values should just remain as they were)
-            (mastodon-tl--set-buffer-spec (mastodon-tl--buffer-name)
-                                          (mastodon-tl--endpoint)
-                                          (mastodon-tl--update-function)
-                                          link-header nil nil max-id)
+            (mastodon-tl--set-buffer-spec
+             (mastodon-tl--buffer-name)
+             (mastodon-tl--endpoint)
+             (mastodon-tl--update-function)
+             link-header (mastodon-tl--update-params)
+             (mastodon-tl--hide-replies-p) max-id)
             (message "Loading... done.")))))))
 
 (defun mastodon-tl--find-property-range (property start-point
@@ -3507,7 +3618,8 @@ This location is defined by a non-nil value of
   "Update timeline with new toots."
   (interactive)
   ;; FIXME: actually these buffers should just reload by calling their own
-  ;; load function (actually g is mostly mapped as such):
+  ;; load function (actually g is mostly mapped as such)
+  ;; well actually, g should be for reload, update is different.
   (if (or (member (mastodon-tl--get-buffer-type)
                   '(trending-statuses
                     trending-tags
diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el
index 9ebb1ef0c7..697e582049 100644
--- a/lisp/mastodon-toot.el
+++ b/lisp/mastodon-toot.el
@@ -258,7 +258,7 @@ send.")
 
 (defvar mastodon-toot-tag-regex
   (rx (| (any ?\( "\n" "\t" " ") bol)
-      (group-n 2 ?# (+ (any "A-Z" "a-z" "0-9")))
+      (group-n 2 ?# (+ (any "_" "A-Z" "a-z" "0-9")))
       (| "'" word-boundary))) ; boundary or possessive
 
 (defvar mastodon-toot-emoji-regex
@@ -1486,8 +1486,9 @@ Return a cons of a human readable string, and a 
seconds-from-now string."
          (response (completing-read "poll ends in [or enter seconds]: "
                                     options nil 'confirm)))
     (or (assoc response options #'string=)
-        (if (< (string-to-number response) 600)
-            (car options))))) ;; min 5 mins
+        (if (< (string-to-number response) 300)
+            (cons "5 minutes" (number-to-string (* 60 5))) ;; min 5 mins
+         (cons (format "%s seconds" response) response)))))
 
 (defun mastodon-toot--poll-expiry-options-alist ()
   "Return an alist of expiry options options in seconds."
diff --git a/lisp/mastodon.el b/lisp/mastodon.el
index 1e973d78de..185a85edd9 100644
--- a/lisp/mastodon.el
+++ b/lisp/mastodon.el
@@ -6,7 +6,7 @@
 ;; Author: Johnson Denen <johnson.de...@gmail.com>
 ;;         Marty Hiatt <mouse...@disroot.org>
 ;; Maintainer: Marty Hiatt <mouse...@disroot.org>
-;; Version: 2.0.0
+;; Version: 2.0.1
 ;; Package-Requires: ((emacs "28.1") (persist "0.4") (tp "0.7"))
 ;; Homepage: https://codeberg.org/martianh/mastodon.el
 
@@ -73,6 +73,8 @@
 (when (require 'lingva nil :no-error)
   (autoload 'mastodon-toot-translate-toot-text "mastodon-toot"))
 (autoload 'mastodon-toot--view-toot-history "mastodon-tl")
+(autoload 'mastodon-tl-return "mastodon-tl")
+(autoload 'mastodon-tl-jump-to-followed-tag "mastodon-tl")
 
 ;; for M-x visibility
 ;; (views.el uses `mastodon-mode-map', so we can't easily require it)
@@ -228,6 +230,7 @@ Also nil `mastodon-auth--token-alist'."
     ;; navigation between timelines
     (define-key map (kbd "#")      #'mastodon-tl-get-tag-timeline)
     (define-key map (kbd "\"")     #'mastodon-tl-list-followed-tags)
+    (define-key map (kbd "C-\"")     #'mastodon-tl-jump-to-followed-tag)
     (define-key map (kbd "'")      #'mastodon-tl-followed-tags-timeline)
     (define-key map (kbd "C-'")   #'mastodon-tl-tag-group-timeline)
     (define-key map (kbd "A")      #'mastodon-profile-get-toot-author)
@@ -256,7 +259,7 @@ Also nil `mastodon-auth--token-alist'."
     (define-key map (kbd "v")      #'mastodon-tl-poll-vote)
     (define-key map (kbd "E")      #'mastodon-toot-view-toot-edits)
     (define-key map (kbd "T")      #'mastodon-tl-thread)
-    (define-key map (kbd "RET")    #'mastodon-tl-thread)
+    (define-key map (kbd "RET")    #'mastodon-tl-return)
     (define-key map (kbd "m")      #'mastodon-tl-dm-user)
     (define-key map (kbd "=")      #'mastodon-tl-view-first-full-image)
     (when (require 'lingva nil :no-error)
@@ -518,7 +521,9 @@ If FORCE, do a lookup regardless of the result of 
`mastodon--fedi-url-p'."
           (string-match "^/comment/[[:digit:]]+$" query) ; lemmy
           (string-match "^/@[^/]+/statuses/[[:alnum:]]" query) ; GTS
           (string-match "^/user[s]?/[[:alnum:]_]+/statuses/[[:digit:]]+$" 
query) ; hometown
-          (string-match "^/notes/[[:alnum:]]+$" query))))) ; misskey post
+          (string-match "^/notes/[[:alnum:]]+$" query) ; misskey post
+          (string-match "^/w/[[:alnum:]_]+$" query) ; peertube post
+          ))))
 
 (defun mastodon-live-buffers ()
   "Return a list of open mastodon buffers.
diff --git a/test/mastodon-tl-tests.el b/test/mastodon-tl-tests.el
index a4f6fa8249..6078cf2927 100644
--- a/test/mastodon-tl-tests.el
+++ b/test/mastodon-tl-tests.el
@@ -110,6 +110,35 @@
             (reblogged)))
   "A sample reblogged/boosted toot (parsed json)")
 
+(defconst mastodon-tl-test-empty-display-name
+  '((id . 61208)
+    (created_at . "2017-04-24T19:01:02.000Z")
+    (in_reply_to_id)
+    (in_reply_to_account_id)
+    (sensitive . :json-false)
+    (spoiler_text . "")
+    (visibility . "public")
+    (account (id . 42)
+             (username . "acct42")
+             (acct . "acct42@example.space")
+             (display_name . nil)
+             (locked . :json-false)
+             (created_at . "2017-04-01T00:00:00.000Z")
+             (followers_count . 99)
+             (following_count . 13)
+             (statuses_count . 101)
+             (note . "E"))
+    (media_attachments . ())
+    (mentions . ())
+    (tags . ())
+    (uri . "tag:example.space,2017-04-24:objectId=654321:objectType=Status")
+    (url . "https://example.space/users/acct42/updates/123456789";)
+    (content . "<p>Just some text</p>")
+    (reblogs_count . 0)
+    (favourites_count . 0)
+    (reblog))
+  "A sample toot (parsed json)")
+
 (defconst mastodon-tl--follow-notify-true-response
   "HTTP/1.1 200 OK
 Date: Mon, 20 Dec 2021 13:42:29 GMT
@@ -532,6 +561,24 @@ Strict-Transport-Security: max-age=31536000
                  "7 years, 4 months ago"
                  (plist-get properties 'display)))))))
 
+(ert-deftest mastodon-tl--byline-no-displayname ()
+  "Should not fail when display_name is nil."
+  (let* ((mastodon-tl--show-avatars-p nil)
+         (toot (cons '(reblogged . t) mastodon-tl-test-empty-display-name))
+         (timestamp (cdr (assoc 'created_at toot))))
+    (with-mock
+      (mock (date-to-time timestamp) => '(22782 21551))
+      (mock (mastodon-tl--symbol 'boost) => "B")
+      (mock (mastodon-tl--toot-stats toot) => "")
+      (mock (format-time-string mastodon-toot-timestamp-format '(22782 21551)) 
=> "2999-99-99 00:11:22")
+
+      (should (string= (substring-no-properties
+                        (mastodon-tl--byline toot))
+                       (concat "(B) acct42 (@acct42@example.space) 2999-99-99 
00:11:22
+  "
+                               mastodon-tl--horiz-bar "
+"))))))
+
 (ert-deftest mastodon-tl--consider-timestamp-for-updates-no-active-callback ()
   "Should update the timestamp update variables as expected."
 

Reply via email to