diff --git a/web/src/message_list_view.ts b/web/src/message_list_view.ts index 93de7db21e..e04225eae3 100644 --- a/web/src/message_list_view.ts +++ b/web/src/message_list_view.ts @@ -65,6 +65,7 @@ export type MessageContainer = { msg: Message; sender_is_bot: boolean; sender_is_guest: boolean; + sender_is_deactivated: boolean; should_add_guest_indicator_for_sender: boolean; small_avatar_url: string; status_message: string | false; @@ -662,6 +663,7 @@ export class MessageListView { small_avatar_url: string; sender_is_bot: boolean; sender_is_guest: boolean; + sender_is_deactivated: boolean; should_add_guest_indicator_for_sender: boolean; is_hidden: boolean; mention_classname: string | undefined; @@ -743,6 +745,7 @@ export class MessageListView { const sender_is_bot = people.sender_is_bot(message); const sender_is_guest = people.sender_is_guest(message); + const sender_is_deactivated = people.sender_is_deactivated(message); const should_add_guest_indicator_for_sender = people.should_add_guest_user_indicator( message.sender_id, ); @@ -760,6 +763,7 @@ export class MessageListView { small_avatar_url, sender_is_bot, sender_is_guest, + sender_is_deactivated, should_add_guest_indicator_for_sender, is_hidden, mention_classname, diff --git a/web/src/people.ts b/web/src/people.ts index ec26fa9f29..9a01460fe3 100644 --- a/web/src/people.ts +++ b/web/src/people.ts @@ -778,6 +778,14 @@ export function sender_is_guest(message: Message): boolean { return false; } +export function sender_is_deactivated(message: Message): boolean { + const sender_id = message.sender_id; + if (sender_id) { + return !is_active_user_for_popover(message.sender_id); + } + return false; +} + export function is_valid_bot_user(user_id: number): boolean { const user = maybe_get_user_by_id(user_id, true); return user?.is_bot ?? false; diff --git a/web/src/pm_list_data.ts b/web/src/pm_list_data.ts index a0f65835e1..5715076a95 100644 --- a/web/src/pm_list_data.ts +++ b/web/src/pm_list_data.ts @@ -47,6 +47,7 @@ type DisplayObject = { is_group: boolean; is_bot: boolean; has_unread_mention: boolean; + is_deactivated: boolean; }; export function get_conversations(search_string = ""): DisplayObject[] { @@ -86,6 +87,9 @@ export function get_conversations(search_string = ""): DisplayObject[] { unread.num_unread_mentions_for_user_ids_strings(user_ids_string) > 0; const is_group = user_ids_string.includes(","); const is_active = user_ids_string === active_user_ids_string; + const is_deactivated = !people.is_active_user_for_popover( + Number.parseInt(user_ids_string, 10) || 0, + ); let user_circle_class; let status_emoji_info; @@ -116,6 +120,7 @@ export function get_conversations(search_string = ""): DisplayObject[] { is_group, is_bot, has_unread_mention, + is_deactivated, }; display_objects.push(display_object); } diff --git a/web/styles/app_variables.css b/web/styles/app_variables.css index 77bfe7f946..6b2efb12a2 100644 --- a/web/styles/app_variables.css +++ b/web/styles/app_variables.css @@ -1555,6 +1555,7 @@ --color-user-circle-active: hsl(106deg 74% 44%); --color-user-circle-idle: hsl(29deg 84% 51%); --color-user-circle-offline: hsl(0deg 0% 50%); + --color-user-circle-deactivated: hsl(0deg 0% 50%); --color-copy-button: light-dark( /* hsl(229deg 9% 36%) corresponds to --grey-600. We use the hsl() equivalent directly since postcss-color-mix-function diff --git a/web/styles/input_pill.css b/web/styles/input_pill.css index 7aed5ed494..6d79b684c3 100644 --- a/web/styles/input_pill.css +++ b/web/styles/input_pill.css @@ -16,6 +16,7 @@ align-items: center; max-width: 100%; min-width: 0; + position: relative; height: var(--height-input-pill); /* Make sure the `height` property @@ -109,6 +110,7 @@ &.deactivated-pill { background-color: var(--color-background-deactivated-user-pill); + opacity: 0.7; &:focus { border-color: var(--color-focus-outline-deactivated-user-pill); @@ -124,9 +126,24 @@ --color-background-exit-hover-deactivated-user-pill ); } + + > img { + opacity: 0.5; + } } } + .slashed-circle-icon { + position: absolute; + background-color: var(--color-background-deactivated-user-pill); + padding: 0.2em; + font-size: 0.7em; + border-radius: 0.625em; + bottom: -0.0625em; + left: 1.1em; + opacity: 1; + } + &.not-editable { cursor: not-allowed; border: none; diff --git a/web/styles/popovers.css b/web/styles/popovers.css index 519644c2bf..e1c33d6a7a 100644 --- a/web/styles/popovers.css +++ b/web/styles/popovers.css @@ -1010,6 +1010,12 @@ ul.popover-group-menu-member-list { background-color: var(--color-background-popover-menu); border: solid 1px var(--color-background-popover-menu); border-radius: 50%; + + &.deactivated-user-icon { + font-size: 0.8em; + background-color: var(--color-background-popover-menu); + padding: 1px; + } } .popover-menu-user-info { diff --git a/web/styles/zulip.css b/web/styles/zulip.css index 4bb358eacd..d60b7ab569 100644 --- a/web/styles/zulip.css +++ b/web/styles/zulip.css @@ -2049,3 +2049,23 @@ body:not(.hide-left-sidebar) { .empty-topic-placeholder-display::placeholder { font-style: italic; } + +.popover-menu-user-avatar-container.deactivated, +.inline_profile_picture.deactivated { + position: relative; + + > img { + opacity: 0.5; + } + + .deactivated-user-icon { + background-color: var(--color-background); + color: var(--color-user-circle-deactivated); + padding: 2px; + font-size: 0.8em; + position: absolute; + border-radius: 10px; + bottom: -2px; + right: -2px; + } +} diff --git a/web/templates/input_pill.hbs b/web/templates/input_pill.hbs index 1fd81c0c0d..8da370dcae 100644 --- a/web/templates/input_pill.hbs +++ b/web/templates/input_pill.hbs @@ -1,6 +1,9 @@
{{#if has_image}} + {{#if deactivated}} + + {{/if}} {{/if}} @@ -20,7 +23,6 @@ {{/if}} {{~#if should_add_guest_user_indicator}} ({{t 'guest'}}){{~/if~}} - {{~#if deactivated}} ({{t 'deactivated'}}){{~/if~}} {{~#if has_status~}} {{~> status_emoji status_emoji_info~}} {{~/if~}} diff --git a/web/templates/message_avatar.hbs b/web/templates/message_avatar.hbs index 172e5e4136..59bb29adde 100644 --- a/web/templates/message_avatar.hbs +++ b/web/templates/message_avatar.hbs @@ -1,6 +1,9 @@