Skip to content

Commit

Permalink
Initial support for Telegram Stories and enhancements
Browse files Browse the repository at this point in the history
- [del] `telega-company-username-prefer-username' in favor for
  `telega-company-username-prefer-name`. Fixes #423

- [del] `telega-user--name` removed in favor for
  `telega-user-title` and `telega-ins--msg-sender`

Version -> 0.8.152
  • Loading branch information
zevlg committed Aug 15, 2023
1 parent 2e19682 commit 510e799
Show file tree
Hide file tree
Showing 26 changed files with 850 additions and 244 deletions.
3 changes: 2 additions & 1 deletion contrib/telega-adblock.el
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ the rootbuf."
:options '((contains "#advert"))
:group 'telega-adblock)

(defcustom telega-adblock-allow-msg-temex '(or is-reply post-with-comments)
(defcustom telega-adblock-allow-msg-temex
'(or is-reply-to-msg is-reply-to-story post-with-comments)
"Message's matching this temex will be allowed."
:type 'list
:group 'telega-adblock)
Expand Down
5 changes: 2 additions & 3 deletions contrib/telega-bridge-bot.el
Original file line number Diff line number Diff line change
Expand Up @@ -502,9 +502,8 @@ ARGS is the arguments passed the the FUN."
(if-let* ((modified? (plist-get msg :telega-bridge-bot-modified))
(sender (telega-msg-sender msg))
(sender-name
(concat
(telega-user-title sender 'name) " "
(telega-msg-sender-username sender 'with-@))))
(when (telega-user-p sender)
(telega-user-title sender 'full-name-and-username))))
;; if msg sender is a bridge bot then we want to display
;; the user title and the username in one line message
(cl-letf (((symbol-function 'telega-msg-sender-username)
Expand Down
30 changes: 30 additions & 0 deletions etc/langs/en.plist
Original file line number Diff line number Diff line change
Expand Up @@ -998,6 +998,28 @@ Telegram offers a free and unlimited service to hundreds of millions of users, w
("lng_media_file_title"
:value "Files")
;; media types
("lng_in_dlg_photo"
:value "Photo")
("lng_in_dlg_video"
:value "Video")
("lng_in_dlg_file"
:value "File")
("lng_in_dlg_audio_file"
:value "Audio file")
("lng_in_dlg_sticker"
:value "Sticker")
("lng_in_dlg_audio"
:value "Voice message")
("lng_in_dlg_video_message"
:value "Video message")
("lng_in_dlg_contact"
:value "Contact")
("lng_in_dlg_story"
:value "Story")
("lng_in_dlg_story_expired"
:value "Expired story")
;; Edited
("lng_edited"
:value "edited")
Expand Down Expand Up @@ -1032,9 +1054,17 @@ You can send them an invite link as message instead.")
:value "Last i18n Entry")
;; Stories
("lng_stories_my_name"
:value "My Story")
("lng_view_button_story"
:value "View story")
("lng_contacts_stories_status"
:one_value "{count} story"
:other_value "{count} stories")
("lng_forwarded_story"
:value "Story from {user}")
("lng_forwarded_story_expired"
:value "This story has expired.")
("lng_deleted_story"
:value "Deleted story")
)
67 changes: 45 additions & 22 deletions telega-chat.el
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ Combines chat permissions and admin/owner permissions."
(telega-tl-str chat :title)))
(chat-user (unless raw-title (telega-chat-user chat)))
(title (if chat-user
(telega-user-title chat-user 'name)
(telega-user-title chat-user 'full-name)
(concat
;; NOTE: Channels we are banned in can have empty title
(or raw-title (format "CHAT-%d" (plist-get chat :id)))
Expand Down Expand Up @@ -640,9 +640,14 @@ Specify non-nil BAN to ban this user in this CHAT."
(full-info (telega--full-info user)))
(when (plist-get full-info :has_private_calls)
(error "%s can't be called due to their privacy settings"
(telega-user--name user)))
(telega-msg-sender-title user
:with-avatar-p t
:with-username-p t)))
(unless (plist-get full-info :can_be_called)
(error "%s can't be called" (telega-user--name user)))
(error "%s can't be called"
(telega-msg-sender-title user
:with-avatar-p t
:with-username-p t)))

(telega-voip-call user)))

Expand Down Expand Up @@ -1172,15 +1177,20 @@ Return newly created chat."
'canTransferOwnershipResultOk)
(user-error (concat
(telega-i18n "lng_rights_transfer_check_about"
:user (telega-user--name to-user)) "\n"
(telega-i18n "lng_rights_transfer_check_session") "\n"
(telega-i18n "lng_rights_transfer_check_password") "\n"
(telega-i18n "lng_rights_transfer_check_later"))))
:user (telega-msg-sender-title to-user
:with-avatar-p t
:with-username-p t))
"\n"
(telega-i18n "lng_rights_transfer_check_session") "\n"
(telega-i18n "lng_rights_transfer_check_password") "\n"
(telega-i18n "lng_rights_transfer_check_later"))))

(unless (telega-read-im-sure-p
(concat (telega-i18n "lng_rights_transfer_about"
:group (telega-chat-title chat)
:user (telega-user--name to-user))
:user (telega-msg-sender-title to-user
:with-avatar-p t
:with-username-p t))
"\n"
(telega-i18n "lng_rights_transfer_sure") "?"))
(user-error "Ownership transfer canceled"))
Expand All @@ -1195,7 +1205,9 @@ Return newly created chat."
(telega-i18n (if (telega-chat-channel-p chat)
"lng_rights_transfer_done_channel"
"lng_rights_transfer_done_group")
:user (telega-user--name to-user)))))))
:user (telega-msg-sender-title to-user
:with-avatar-p t
:with-username-p t)))))))
))

(defun telega-chat-set-description (chat descr)
Expand Down Expand Up @@ -1473,7 +1485,8 @@ Used in chatbuf footer."
(telega-ins (telega-symbol 'play)))
(telega-ins " ")
(if sender
(telega-ins (telega-user--name sender))
(telega-ins (telega-msg-sender-title sender
:with-username-p t))
(telega-ins (telega-chat-title (telega-msg-chat msg)))))
(telega-ins " ")
(telega-ins--button "stop"
Expand Down Expand Up @@ -1580,6 +1593,7 @@ Possibly view some messages at point."
;; --(actions part)---------------[additional status]--
;; [x] Messages Filter: <FILTER> (total: MSG-COUNT)
;; [x] Action Bar: [ action ] [ bar ] [ buttons ]
;; [x] Active Stories: [story] [story] ..
;; [x] Voice Chat: <Title> [Join] [Leave] [Show]
;; 5 participants: (A) (B) <-- recent speakers
;; [x] Users restricted adding them to group:
Expand All @@ -1606,6 +1620,8 @@ Possibly view some messages at point."
(display-spec (cdr (assq (if active-p 'active 'passive)
telega-video-chat-display))))
(memq 'footer display-spec))))
(active-stories-visible-p
(not telega-chatbuf--active-stories-hidden))
(msg-filter telega-chatbuf--msg-filter)
(thread-msg telega-chatbuf--thread-msg)
(actions (telega-chat--actions chat (plist-get thread-msg :id)))
Expand Down Expand Up @@ -1739,6 +1755,11 @@ Possibly view some messages at point."
(when (telega-ins--chat-action-bar chat)
(telega-ins "\n"))

;; Active Stories
(when (and active-stories-visible-p
(telega-ins--chat-active-stories chat))
(telega-ins "\n"))

;; List of users that restricts adding them to the group
(when-let ((add-forbidden-users
(plist-get chat :telega-add-member-forbidden-users))
Expand Down Expand Up @@ -2628,7 +2649,15 @@ If message thread filtering is enabled, use it first."
:with-username-p t))
(telega-ins "]"))))

(defun telega-chatbuf--modeline-messages-ttl ()
(defun telega-chatbuf-mode-line-online-status ()
"Format online status for the private chatbuf."
(when (and (telega-chat-private-p telega-chatbuf--chat)
(not (telega-me-p telega-chatbuf--chat))
(telega-user-online-p
(telega-chat-user telega-chatbuf--chat)))
(telega-symbol 'online-status)))

(defun telega-chatbuf-mode-line-messages-ttl ()
"Format TTL messages settings for the chatbuf."
(when-let ((ttl (plist-get telega-chatbuf--chat :message_ttl)))
(when (or (telega-chat-secret-p telega-chatbuf--chat)
Expand Down Expand Up @@ -2665,16 +2694,8 @@ If message thread filtering is enabled, use it first."
(telega-emoji-use-images (unless mode-line-smaller-p
telega-emoji-use-images)))
(setq mode-line-buffer-identification
(list (propertized-buffer-identification "%b")
;; Online status
(when (and (telega-chat-private-p telega-chatbuf--chat)
(not (telega-me-p telega-chatbuf--chat))
(telega-user-online-p
(telega-chat-user telega-chatbuf--chat)))
(telega-symbol 'online-status))
(telega-chatbuf--modeline-messages-ttl)
(format-mode-line telega-chat-mode-line-format nil nil
(current-buffer)))))
(format-mode-line telega-chat-mode-line-format nil nil
(current-buffer))))
(force-mode-line-update))

(defconst telega-chatbuf--modeline-dirtiness
Expand Down Expand Up @@ -3953,7 +3974,9 @@ If `\\[universal-argument]' is given, then attach live location."
(with-telega-chatbuf-action "ChoosingContact"
(let* ((contacts (telega--getContacts))
(names-alist (mapcar (lambda (user)
(cons (telega-user--name user 'full)
(cons (telega-msg-sender-title user
:with-avatar-p t
:with-username-p t)
user))
contacts))
(name (funcall telega-completing-read-function
Expand Down
65 changes: 33 additions & 32 deletions telega-company.el
Original file line number Diff line number Diff line change
Expand Up @@ -224,39 +224,40 @@ Matches only if CHAR does not apper in the middle of the word."
(telega-ins--msg-sender member
:with-avatar-p telega-company-username-show-avatars))))
(post-completion
(when-let* ((input (get-text-property 0 'telega-input arg))
(member (get-text-property 0 'telega-member arg))
(username (or (telega-msg-sender-username member 'with-@) "")))
;; NOTE: Complete by username only if username starts with the
;; `input', see https://t.me/emacs_telega/38371
;; Behaviour is controlled by
;; `telega-company-username-prefer-username' user option
(unless (telega-chat-p member)
(when-let ((input (get-text-property 0 'telega-input arg))
(member (get-text-property 0 'telega-member arg)))
;; Name you get after completion is controlled by
;; `telega-company-username-prefer-name' user option
(when (telega-user-p member)
(delete-region (- (point) (length arg)) (point))

(telega-ins
(cond ((and telega-company-username-prefer-username
(not (string-empty-p username)))
username)

((member telega-company-username-markup
'("markdown1" "markdown2"))
(telega-string-as-markup
(format "[%s](tg://user?id=%d)"
(telega-msg-sender-title member)
(plist-get member :id))
telega-company-username-markup
(cdr (assoc telega-company-username-markup
telega-chat-markup-functions))))
(t
(propertize
(telega-msg-sender-title member)
:tl-entity-type (list :@type "textEntityTypeMentionName"
:user_id (plist-get member :id))
'face 'telega-entity-type-mention
;; NOTE: Do not use `rear-nonsticky' property, so username
;; can be edited, see https://t.me/emacs_telega/38257
))))))
(when-let* ((fmt-names telega-company-username-prefer-name)
(name (let ((tmp-name nil))
(while (and fmt-names (not tmp-name))
(setq tmp-name (telega-user-title
member (car fmt-names))
fmt-names (cdr fmt-names)))
tmp-name)))
(telega-ins
(cond ((string-prefix-p "@" name)
name)

((member telega-company-username-markup
'("markdown1" "markdown2"))
(telega-string-as-markup
(format "[%s](tg://user?id=%d)"
name (plist-get member :id))
telega-company-username-markup
(cdr (assoc telega-company-username-markup
telega-chat-markup-functions))))
(t
(propertize
name
:tl-entity-type (list :@type "textEntityTypeMentionName"
:user_id (plist-get member :id))
'face 'telega-entity-type-mention
;; NOTE: Do not use `rear-nonsticky' property, so username
;; can be edited, see https://t.me/emacs_telega/38257
)))))))
(insert " ")
(let ((chatbuf-input (telega-chatbuf-input-string)))
(when (or (member chatbuf-input telega-known-inline-bots)
Expand Down
14 changes: 14 additions & 0 deletions telega-core.el
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,17 @@ Used for optimisations.")
"Aux status used for long requests, such as fetching chats/searching/etc")
(defvar telega--chats nil "Hash table (id -> chat) for all chats.")
(defvar telega--chat-topics nil "Hash table (id -> topics list) for forums chats.")
(defvar telega--story-list-chat-count nil
"Plist with number of chats having active stories.
Props are `main' and `archive'.")
(defvar telega--chat-active-stories nil
"Hash table (chat-id -> chatActiveStories) for chat's stories.")

(defvar telega--cached-messages nil
"Hash table ((chat-id . msg-id) -> msg) of cached messages.
Such as pinned, replies, etc.")
(defvar telega--cached-stories nil
"Hash table ((chat-id . story-id) -> story) of cached stories.")
(defvar telega--actions nil
"Hash table ((chat-id . msg-thread-id) -> alist-of-user-actions).")
(defvar telega--ordered-chats nil "Ordered list of all chats.")
Expand Down Expand Up @@ -434,6 +442,9 @@ Actual value is `:@extra` value of the call to inline bot.")
Asynchronously loaded when chatbuf is created.")
(make-variable-buffer-local 'telega-chatbuf--administrators)

(defvar telega-chatbuf--active-stories-hidden nil
"Non-nil if active stories should not be displayed in the footer.")
(make-variable-buffer-local 'telega-chatbuf--active-stories-hidden)
(defvar telega-chatbuf--video-chat-hidden nil
"Non-nil if non-empty video chat is displayed in modeline instead of footer.")
(make-variable-buffer-local 'telega-chatbuf--video-chat-hidden)
Expand Down Expand Up @@ -484,7 +495,9 @@ Done when telega server is ready to receive queries."
:message_text_length_max 4096))
(setq telega--chats (make-hash-table :test #'eq))
(setq telega--chat-topics (make-hash-table :test #'eq))
(setq telega--chat-active-stories (make-hash-table :test #'eq))
(setq telega--cached-messages (make-hash-table :test #'equal))
(setq telega--cached-stories (make-hash-table :test #'equal))
(setq telega--top-chats nil)

(setq telega--search-chats nil)
Expand Down Expand Up @@ -515,6 +528,7 @@ Done when telega server is ready to receive queries."
(make-ring telega-ignored-messages-ring-size))
(setq telega--unread-message-count nil)
(setq telega--unread-chat-count nil)
(setq telega--story-list-chat-count nil)

(setq telega--files (make-hash-table :test 'eq))
(setq telega--files-updates (make-hash-table :test 'eq))
Expand Down
26 changes: 17 additions & 9 deletions telega-customize.el
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ Resulting string must be no longer then 8 chars. Format specifiers:
:group 'telega)

(defcustom telega-use-tracking-for nil
"*Specifies Chat Filter for chats to be tracked with tracking.el.
"*Specifies Chat Temex for chats to be tracked with tracking.el.
Make sure you have tracking.el loaded if this option is used.
Only chats with corresponding opened chatbuf are tracked.
Tracking notifications for telega buffers will use the
Expand Down Expand Up @@ -1209,11 +1209,14 @@ Done by recentering point in the chatbuf."
:type 'list
:group 'telega-company)

(defcustom telega-company-username-prefer-username t
"Non-nil to prefer username for the username completion.
Set to nil to complete user to a username or full name depending on input."
:package-version '(telega . "0.8.121")
:type 'boolean
(defcustom telega-company-username-prefer-name '(username first-name last-name)
"Preferred formatting argument to the `telega-user-title' to complete user.
Frist giving non-nil result will be used."
:package-version '(telega . "0.8.152")
:type '(list (choice (const :tag "Username" username)
(const :tag "First Name" first-name)
(const :tag "Last Name" last-name)
(const :tag "Full Name" full-name)))
:group 'telega-company)


Expand Down Expand Up @@ -1469,16 +1472,21 @@ timespan, then do not group messages."
:group 'telega-chat)

(defcustom telega-chat-mode-line-format
'((:eval (telega-chatbuf-mode-line-video-chat 20))
'(
;; NOTE: Truncate buffer name to 32 chars
(-32 (:eval (propertized-buffer-identification "%b")))
(:eval (telega-chatbuf-mode-line-online-status))
(:eval (telega-chatbuf-mode-line-messages-ttl))
(:eval (telega-chatbuf-mode-line-video-chat 20))
(:eval (telega-chatbuf-mode-line-discuss))
(:eval (telega-chatbuf-mode-line-unread))
(:eval (telega-chatbuf-mode-line-marked))
(:eval (telega-chatbuf-mode-line-members 'use-icons))
(:eval (telega-chatbuf-mode-line-pinned-or-thread-msg 20))
(:eval (telega-chatbuf-mode-line-messages-filter)))
"Additional mode line format for chat buffer identification.
"Mode line format for chat buffer identification.
See `mode-line-buffer-identification'."
:package-version '(telega . "0.7.35")
:package-version '(telega . "0.8.151")
:type 'sexp
:group 'telega-chat)

Expand Down
Loading

0 comments on commit 510e799

Please sign in to comment.