diff --git a/tools/lib/capitalization.py b/tools/lib/capitalization.py
index 17afcd37f8..efc49a0aca 100644
--- a/tools/lib/capitalization.py
+++ b/tools/lib/capitalization.py
@@ -164,6 +164,8 @@ IGNORED_PHRASES = [
r"does not apply to users who can delete any message",
# Used as indicator with names for guest users.
r"guest",
+ # Used as indicator with names for archived streams.
+ r"archived",
# Used in pills for deactivated users.
r"deactivated",
# This is a reference to a setting/secret and should be lowercase.
diff --git a/web/src/inbox_ui.ts b/web/src/inbox_ui.ts
index e668caa5a3..78405978c3 100644
--- a/web/src/inbox_ui.ts
+++ b/web/src/inbox_ui.ts
@@ -71,6 +71,7 @@ const direct_message_context_properties: (keyof DirectMessageContext)[] = [
type StreamContext = {
is_stream: boolean;
+ is_archived: boolean;
invite_only: boolean;
is_web_public: boolean;
stream_name: string;
@@ -372,6 +373,7 @@ function format_stream(stream_id: number): StreamContext {
return {
is_stream: true,
+ is_archived: stream_info.is_archived,
invite_only: stream_info.invite_only,
is_web_public: stream_info.is_web_public,
stream_name: stream_info.name,
diff --git a/web/src/message_list.ts b/web/src/message_list.ts
index ab60d4d519..6b62a7a545 100644
--- a/web/src/message_list.ts
+++ b/web/src/message_list.ts
@@ -432,7 +432,7 @@ export class MessageList {
const is_web_public = sub?.is_web_public;
const can_toggle_subscription =
sub !== undefined && stream_data.can_toggle_subscription(sub);
- if (sub === undefined) {
+ if (sub === undefined || sub.is_archived) {
deactivated = true;
} else if (!subscribed && !this.last_message_historical) {
just_unsubscribed = true;
diff --git a/web/src/message_list_view.ts b/web/src/message_list_view.ts
index 25b951ac48..c72e469e20 100644
--- a/web/src/message_list_view.ts
+++ b/web/src/message_list_view.ts
@@ -99,6 +99,7 @@ export type MessageGroup = {
stream_name?: string;
stream_privacy_icon_color: string;
stream_url: string;
+ is_archived: boolean;
subscribed?: boolean;
topic: string;
topic_is_resolved: boolean;
@@ -468,6 +469,7 @@ function populate_group_from_message(
const topic = message.topic;
const match_topic = util.get_match_topic(message);
const stream_url = hash_util.by_stream_url(message.stream_id);
+ const is_archived = stream_data.is_stream_archived(message.stream_id);
const topic_url = hash_util.by_stream_topic_url(message.stream_id, message.topic);
const sub = sub_store.get(message.stream_id);
@@ -508,6 +510,7 @@ function populate_group_from_message(
is_web_public,
match_topic,
stream_url,
+ is_archived,
topic_url,
stream_id,
is_subscribed,
diff --git a/web/src/server_events_dispatch.js b/web/src/server_events_dispatch.js
index dcc5b28fa3..c1944fa358 100644
--- a/web/src/server_events_dispatch.js
+++ b/web/src/server_events_dispatch.js
@@ -28,6 +28,7 @@ import * as message_edit from "./message_edit";
import * as message_events from "./message_events";
import * as message_lists from "./message_lists";
import * as message_live_update from "./message_live_update";
+import * as message_view_header from "./message_view_header";
import * as muted_users_ui from "./muted_users_ui";
import * as narrow_state from "./narrow_state";
import * as narrow_title from "./narrow_title";
diff --git a/web/src/stream_data.ts b/web/src/stream_data.ts
index 4e7a26d958..985d580b72 100644
--- a/web/src/stream_data.ts
+++ b/web/src/stream_data.ts
@@ -629,6 +629,11 @@ export function get_stream_privacy_policy(stream_id: number): string {
return settings_config.stream_privacy_policy_values.private_with_public_history.code;
}
+export function is_stream_archived(stream_id: number): boolean {
+ const sub = sub_store.get(stream_id);
+ return sub ? sub.is_archived : false;
+}
+
export function is_web_public(stream_id: number): boolean {
const sub = sub_store.get(stream_id);
return sub ? sub.is_web_public : false;
diff --git a/web/styles/app_variables.css b/web/styles/app_variables.css
index 59547706a4..ae27406cf5 100644
--- a/web/styles/app_variables.css
+++ b/web/styles/app_variables.css
@@ -716,6 +716,7 @@
/* Text colors */
--color-text-default: hsl(0deg 0% 20%);
--color-text-message-default: hsl(0deg 0% 15%);
+ --color-text-message-header-archived: hsl(0deg 0% 50%);
--color-text-message-view-header: hsl(0deg 0% 20% / 100%);
--color-text-message-header: hsl(0deg 0% 15%);
/* Light and dark mode both use the same hover color on
diff --git a/web/styles/inbox.css b/web/styles/inbox.css
index cd56924f12..49596c7ab7 100644
--- a/web/styles/inbox.css
+++ b/web/styles/inbox.css
@@ -479,6 +479,10 @@
}
}
}
+
+ .inbox-header-stream-archived {
+ color: var(--color-text-message-header-archived);
+ }
}
#inbox-view {
diff --git a/web/styles/message_header.css b/web/styles/message_header.css
index 0c9686a108..84d832d957 100644
--- a/web/styles/message_header.css
+++ b/web/styles/message_header.css
@@ -210,6 +210,15 @@
}
}
}
+
+ .message-header-stream-name {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+
+ .message-header-stream-archived {
+ color: var(--color-text-message-header-archived);
+ }
}
.recipient_bar_controls {
diff --git a/web/styles/message_view_header.css b/web/styles/message_view_header.css
index d677bc1b99..8401e5b28c 100644
--- a/web/styles/message_view_header.css
+++ b/web/styles/message_view_header.css
@@ -66,6 +66,12 @@
text-overflow: ellipsis;
}
+ .message-header-archived {
+ color: var(--color-text-message-header-archived);
+ cursor: default;
+ padding-left: 5px;
+ }
+
.narrow_description {
/* Flexbox's baseline alignment is responsible for
matching the description's baseline to the title.
diff --git a/web/templates/inbox_view/inbox_stream_header_row.hbs b/web/templates/inbox_view/inbox_stream_header_row.hbs
index 706034e9d7..779478298d 100644
--- a/web/templates/inbox_view/inbox_stream_header_row.hbs
+++ b/web/templates/inbox_view/inbox_stream_header_row.hbs
@@ -9,6 +9,11 @@
{{> ../stream_privacy }}
{{stream_name}}
+ {{#if is_archived}}
+
+ {{/if}}