UI: Add Zulip version in gear menu.

Currently only enabled in development, since the exact details don't
seem right..

Co-Author-By: Signior-X <b19188@students.iitmandi.ac.in>
Co-Author-By: Aman Agrawal <amanagr@zulip.com>

Implements UI for #8005.
This commit is contained in:
pilgrim2308 2021-02-09 15:46:52 +05:30 committed by Tim Abbott
parent daabc52a78
commit a74b52db22
14 changed files with 162 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 991 B

17
static/js/about_zulip.js Normal file
View File

@ -0,0 +1,17 @@
import ClipboardJS from "clipboard";
import $ from "jquery";
import * as browser_history from "./browser_history";
import * as overlays from "./overlays";
export function launch() {
overlays.open_overlay({
name: "about-zulip",
overlay: $("#about-zulip"),
on_close() {
browser_history.exit_overlay();
},
});
new ClipboardJS("#about-zulip .fa-copy");
}

View File

@ -26,6 +26,7 @@ link: Help center
info: Keyboard shortcuts info: Keyboard shortcuts
info: Message formatting info: Message formatting
info: Search operators info: Search operators
hash: About Zulip
--- ---
link: Desktop & mobile apps link: Desktop & mobile apps
link: Integrations link: Integrations
@ -53,6 +54,7 @@ links:
#streams #streams
#settings #settings
#organization #organization
#about-zulip
#invite #invite
When you click on the links there is a function When you click on the links there is a function

View File

@ -227,6 +227,7 @@ export function is_overlay_hash(hash) {
"keyboard-shortcuts", "keyboard-shortcuts",
"message-formatting", "message-formatting",
"search-operators", "search-operators",
"about-zulip",
]; ];
const main_hash = get_hash_category(hash); const main_hash = get_hash_category(hash);

View File

@ -1,5 +1,6 @@
import $ from "jquery"; import $ from "jquery";
import * as about_zulip from "./about_zulip";
import * as admin from "./admin"; import * as admin from "./admin";
import * as blueslip from "./blueslip"; import * as blueslip from "./blueslip";
import * as browser_history from "./browser_history"; import * as browser_history from "./browser_history";
@ -154,6 +155,7 @@ function do_hashchange_normal(from_reload) {
case "#streams": case "#streams":
case "#organization": case "#organization":
case "#settings": case "#settings":
case "#about-zulip":
blueslip.error("overlay logic skipped for: " + hash); blueslip.error("overlay logic skipped for: " + hash);
break; break;
} }
@ -277,6 +279,10 @@ function do_hashchange_overlay(old_hash) {
info_overlay.show("search-operators"); info_overlay.show("search-operators");
return; return;
} }
if (base === "about-zulip") {
about_zulip.launch();
}
} }
function hashchanged(from_reload, e) { function hashchanged(from_reload, e) {

View File

@ -517,3 +517,9 @@ div.overlay {
font-weight: 600; font-weight: 600;
} }
} }
.white_zulip_icon_without_text {
display: inline-block;
background-image: url(../../static/images/logo/white-zulip-logo-without-text.svg);
background-size: cover;
}

View File

@ -318,6 +318,19 @@ on a dark background, and don't change the dark labels dark either. */
opacity: 0.2; opacity: 0.2;
} }
#about-zulip {
.about-zulip-version {
color: hsl(212, 17%, 81%);
}
}
#gear_menu_about_zulip {
.white_zulip_icon_without_text {
filter: invert(10%) sepia(16%) saturate(175%) hue-rotate(194deg)
brightness(99%) contrast(89%);
}
}
.nav .dropdown-menu::after, .nav .dropdown-menu::after,
.popover.bottom .arrow { .popover.bottom .arrow {
border-bottom-color: hsl(235, 18%, 7%); border-bottom-color: hsl(235, 18%, 7%);

View File

@ -699,6 +699,28 @@ li.actual-dropdown-menu i {
margin-right: 3px; margin-right: 3px;
} }
#gear_menu_about_zulip {
.white_zulip_icon_without_text {
position: relative;
top: 3px;
width: 14px;
height: 14px;
margin-right: 3px;
filter: invert(20%) sepia(11%) saturate(0%) hue-rotate(272deg)
brightness(20%) contrast(95%);
}
.about_zulip_text {
position: relative;
top: 1.4px;
}
:hover {
.white_zulip_icon_without_text {
filter: none;
}
}
}
.settings-dropdown-cog { .settings-dropdown-cog {
padding: 6px 12px; padding: 6px 12px;
} }
@ -2666,6 +2688,57 @@ select.inline_select_topic_edit {
display: none; display: none;
} }
#about-zulip {
.exit {
font-size: 1.5rem;
font-weight: 600;
background-color: transparent;
border: none;
position: absolute;
right: 8px;
z-index: 1;
color: hsl(0, 0%, 67%);
}
.overlay-content {
position: relative;
width: 300px;
border-radius: 4px;
}
.modal-body {
display: flex;
flex-direction: column;
align-items: center;
}
.about-zulip-logo {
padding-top: 20px;
height: 70px;
}
.about-zulip-title {
font-weight: 600;
padding: 10px;
}
.about-zulip-version {
color: hsl(222, 8%, 28%);
.fa-copy {
padding-left: 3px;
}
:hover {
cursor: pointer;
.fa-copy {
color: hsl(0, 0%, 0%);
}
}
}
}
/* This max-width must be synced with message_viewport.is_narrow */ /* This max-width must be synced with message_viewport.is_narrow */
@media (width < $xl_min) { @media (width < $xl_min) {
.app-main, .app-main,

View File

@ -0,0 +1,16 @@
<div id="about-zulip" class="overlay flex new-style" tabindex="-1" role="dialog" data-overlay="about-zulip"
aria-labelledby="about-zulip-label" aria-hidden="true">
<div class="overlay-content modal-bg">
<button type="button" class="exit" aria-label="{{ _('Close') }}"><span aria-hidden="true">&times;</span></button>
<div class="modal-body">
<img class="about-zulip-logo" src="/static/images/logo/zulip-icon-128x128.png" alt="" />
<div class="about-zulip-title">Zulip</div>
<p class="about-zulip-version">
{{zulip_version_name}}
<i class="fa fa-copy tippy-zulip-tooltip" data-tippy-content="Copy version" data-tippy-placement="right" data-clipboard-text="{{zulip_version}}"></i>
</p>
<p>
Zulip is <a target="_blank" rel="noopener noreferrer" href="https://github.com/zulip/zulip">open-source software</a>.</p>
</div>
</div>
</div>

View File

@ -173,6 +173,7 @@
{% include "zerver/app/invite_user.html" %} {% include "zerver/app/invite_user.html" %}
{% include "zerver/app/logout.html" %} {% include "zerver/app/logout.html" %}
{% include "zerver/app/deprecation_notice.html" %} {% include "zerver/app/deprecation_notice.html" %}
{% include "zerver/app/about-zulip.html" %}
<div id="user-profile-modal-holder"></div> <div id="user-profile-modal-holder"></div>
<div id="delete-topic-modal-holder"></div> <div id="delete-topic-modal-holder"></div>
<div class="left-sidebar-modal-holder"></div> <div class="left-sidebar-modal-holder"></div>

View File

@ -104,6 +104,14 @@
</a> </a>
</li> </li>
{% endif %} {% endif %}
{% if development_environment %}
<li role="presentation" id="gear_menu_about_zulip">
<a href="#about-zulip" role="menuitem" class="menuitem-version">
<span class="white_zulip_icon_without_text"></span>
<span class="about_zulip_text">{{ _("About Zulip") }}</span>
</a>
</li>
{% endif %}
<li class="divider" role="presentation"></li> <li class="divider" role="presentation"></li>
<li role="presentation"> <li role="presentation">
<a href="{{ apps_page_url }}" target="_blank" rel="noopener noreferrer" role="menuitem"> <a href="{{ apps_page_url }}" target="_blank" rel="noopener noreferrer" role="menuitem">

View File

@ -35,6 +35,7 @@ USAGE = """
# We do not yet require 100% line coverage for these files: # We do not yet require 100% line coverage for these files:
EXEMPT_FILES = { EXEMPT_FILES = {
"static/js/about_zulip.js",
"static/js/admin.js", "static/js/admin.js",
"static/js/alert_popup.ts", "static/js/alert_popup.ts",
"static/js/archive.js", "static/js/archive.js",

View File

@ -49,6 +49,13 @@ def common_context(user: UserProfile) -> Dict[str, Any]:
} }
def get_zulip_version_name(zulip_version: str) -> str:
if zulip_version.endswith("+git"):
return "Zulip " + zulip_version[:-4]
return "Zulip " + zulip_version
def get_realm_from_request(request: HttpRequest) -> Optional[Realm]: def get_realm_from_request(request: HttpRequest) -> Optional[Realm]:
if hasattr(request, "user") and hasattr(request.user, "realm"): if hasattr(request, "user") and hasattr(request.user, "realm"):
return request.user.realm return request.user.realm
@ -135,6 +142,8 @@ def zulip_default_context(request: HttpRequest) -> Dict[str, Any]:
"request_language": get_language(), "request_language": get_language(),
} }
ZULIP_VERSION_NAME = get_zulip_version_name(ZULIP_VERSION)
context = { context = {
"root_domain_landing_page": settings.ROOT_DOMAIN_LANDING_PAGE, "root_domain_landing_page": settings.ROOT_DOMAIN_LANDING_PAGE,
"custom_logo_url": settings.CUSTOM_LOGO_URL, "custom_logo_url": settings.CUSTOM_LOGO_URL,
@ -160,6 +169,7 @@ def zulip_default_context(request: HttpRequest) -> Dict[str, Any]:
"password_min_length": settings.PASSWORD_MIN_LENGTH, "password_min_length": settings.PASSWORD_MIN_LENGTH,
"password_min_guesses": settings.PASSWORD_MIN_GUESSES, "password_min_guesses": settings.PASSWORD_MIN_GUESSES,
"zulip_version": ZULIP_VERSION, "zulip_version": ZULIP_VERSION,
"zulip_version_name": ZULIP_VERSION_NAME,
"user_is_authenticated": user_is_authenticated, "user_is_authenticated": user_is_authenticated,
"settings_path": settings_path, "settings_path": settings_path,
"secrets_path": secrets_path, "secrets_path": secrets_path,

View File

@ -0,0 +1,8 @@
from zerver.context_processors import get_zulip_version_name
from zerver.lib.test_classes import ZulipTestCase
class TestContextProcessors(ZulipTestCase):
def test_get_zulip_version_name(self) -> None:
self.assertEqual(get_zulip_version_name("4.0-dev+git"), "Zulip 4.0-dev")
self.assertEqual(get_zulip_version_name("4.0"), "Zulip 4.0")