mirror of
https://github.com/zulip/zulip.git
synced 2026-07-12 21:04:41 +08:00
This logic threw an exception ever since we added new buttons at the bottom of the page that were inside the container this looped over.
382 lines
12 KiB
JavaScript
382 lines
12 KiB
JavaScript
import $ from "jquery";
|
|
import _ from "lodash";
|
|
|
|
import * as blueslip from "../blueslip";
|
|
import * as common from "../common";
|
|
import {$t} from "../i18n";
|
|
|
|
import * as google_analytics from "./google-analytics";
|
|
import {path_parts} from "./landing-page";
|
|
|
|
// these constants are populated immediately with data from the DOM on page load
|
|
// name -> display name
|
|
const INTEGRATIONS = new Map();
|
|
const CATEGORIES = new Map();
|
|
|
|
function load_data() {
|
|
for (const integration of $(".integration-lozenge")) {
|
|
const name = $(integration).data("name");
|
|
const display_name = $(integration).find(".integration-name").text().trim();
|
|
|
|
if (display_name && name) {
|
|
INTEGRATIONS.set(name, display_name);
|
|
}
|
|
}
|
|
|
|
for (const category of $(".integration-category")) {
|
|
const name = $(category).data("category");
|
|
const display_name = $(category).text().trim();
|
|
|
|
if (display_name && name) {
|
|
CATEGORIES.set(name, display_name);
|
|
}
|
|
}
|
|
}
|
|
|
|
const INITIAL_STATE = {
|
|
category: "all",
|
|
integration: null,
|
|
query: "",
|
|
};
|
|
|
|
let state = {...INITIAL_STATE};
|
|
|
|
function adjust_font_sizing() {
|
|
for (const integration of $(".integration-lozenge")) {
|
|
const $integration_name = $(integration).find(".integration-name");
|
|
const $integration_category = $(integration).find(".integration-category");
|
|
|
|
// if the text has wrapped to two lines, decrease font-size
|
|
if ($integration_name.height() > 30) {
|
|
$integration_name.css("font-size", "1em");
|
|
if ($integration_name.height() > 30) {
|
|
$integration_name.css("font-size", ".95em");
|
|
}
|
|
}
|
|
|
|
if ($integration_category.height() > 30) {
|
|
$integration_category.css("font-size", ".8em");
|
|
if ($integration_category.height() > 30) {
|
|
$integration_category.css("font-size", ".75em");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function update_path() {
|
|
let next_path;
|
|
if (state.integration) {
|
|
next_path = $(`.integration-lozenge[data-name="${CSS.escape(state.integration)}"]`)
|
|
.closest("a")
|
|
.attr("href");
|
|
} else if (state.category) {
|
|
next_path = $(`.integration-category[data-category="${CSS.escape(state.category)}"]`)
|
|
.closest("a")
|
|
.attr("href");
|
|
} else {
|
|
next_path = "/";
|
|
}
|
|
|
|
window.history.pushState(state, "", next_path);
|
|
google_analytics.config({page_path: next_path});
|
|
}
|
|
|
|
function update_categories() {
|
|
$(".integration-lozenges").css("opacity", 0);
|
|
|
|
$(".integration-category").removeClass("selected");
|
|
$(`[data-category="${CSS.escape(state.category)}"]`).addClass("selected");
|
|
|
|
const $dropdown_label = $(".integration-categories-dropdown .dropdown-category-label");
|
|
if (state.category === INITIAL_STATE.category) {
|
|
$dropdown_label.text($t({defaultMessage: "Filter by category"}));
|
|
} else {
|
|
$dropdown_label.text(CATEGORIES.get(state.category));
|
|
}
|
|
|
|
$(".integration-lozenges").animate({opacity: 1}, {duration: 400});
|
|
|
|
adjust_font_sizing();
|
|
}
|
|
|
|
const update_integrations = _.debounce(() => {
|
|
const max_scrollY = window.scrollY;
|
|
|
|
for (const integration of $(".integration-lozenges").find(".integration-lozenge")) {
|
|
const $integration = $(integration);
|
|
const $integration_category = $integration.find(".integration-category");
|
|
|
|
if (state.category !== "all") {
|
|
$integration_category.css("display", "none");
|
|
$integration.addClass("without-category");
|
|
} else {
|
|
$integration_category.css("display", "");
|
|
$integration.removeClass("without-category");
|
|
}
|
|
|
|
if (!$integration.hasClass("integration-create-your-own")) {
|
|
const display_name = INTEGRATIONS.get($integration.data("name"));
|
|
const display =
|
|
common.phrase_match(state.query, display_name) &&
|
|
($integration.data("categories").includes(CATEGORIES.get(state.category)) ||
|
|
state.category === "all");
|
|
|
|
if (display) {
|
|
$integration.css("display", "inline-block");
|
|
} else {
|
|
$integration.css("display", "none");
|
|
}
|
|
}
|
|
|
|
document.body.scrollTop = Math.min(window.scrollY, max_scrollY);
|
|
}
|
|
|
|
adjust_font_sizing();
|
|
}, 50);
|
|
|
|
function hide_catalog_show_integration() {
|
|
const $lozenge_icon = $(
|
|
`.integration-lozenge.integration-${CSS.escape(state.integration)}`,
|
|
).clone(false);
|
|
$lozenge_icon.removeClass("legacy");
|
|
|
|
const categories = $(`.integration-${CSS.escape(state.integration)}`)
|
|
.data("categories")
|
|
.slice(1, -1)
|
|
.split(",")
|
|
.map((category) => category.trim().slice(1, -1));
|
|
|
|
function show_integration(doc) {
|
|
$("#integration-instructions-group .name").text(INTEGRATIONS.get(state.integration));
|
|
$("#integration-instructions-group .categories .integration-category").remove();
|
|
for (const category of categories) {
|
|
let link;
|
|
for (const [name, display_name] of CATEGORIES) {
|
|
if (display_name === category) {
|
|
link = name;
|
|
}
|
|
}
|
|
const category_el = $("<a></a>")
|
|
.attr("href", "/integrations/" + link)
|
|
.append('<h3 class="integration-category"></h3>');
|
|
category_el.find(".integration-category").attr("data-category", link).text(category);
|
|
$("#integration-instructions-group .categories").append(category_el);
|
|
}
|
|
$("#integration-instructions-group").css({
|
|
opacity: 0,
|
|
display: "flex",
|
|
});
|
|
$(".integration-instructions").css("display", "none");
|
|
$(`#${CSS.escape(state.integration)}.integration-instructions .help-content`).html(doc);
|
|
$("#integration-instruction-block .integration-lozenge").remove();
|
|
$("#integration-instruction-block").append($lozenge_icon).css("display", "flex");
|
|
$(`.integration-instructions#${CSS.escape(state.integration)}`).css("display", "block");
|
|
|
|
$("html, body").animate({scrollTop: 0}, {duration: 200});
|
|
$("#integration-instructions-group").animate({opacity: 1}, {duration: 300});
|
|
|
|
adjust_font_sizing();
|
|
}
|
|
|
|
function hide_catalog(doc) {
|
|
$(".integration-categories-dropdown").css("display", "none");
|
|
$(".integrations .catalog").addClass("hide");
|
|
$(".extra, #integration-main-text, #integration-search").css("display", "none");
|
|
|
|
show_integration(doc);
|
|
$(".main").css("visibility", "visible");
|
|
}
|
|
|
|
$.get({
|
|
url: "/integrations/doc-html/" + state.integration,
|
|
dataType: "html",
|
|
success: hide_catalog,
|
|
error(err) {
|
|
blueslip.error(
|
|
"Integration documentation for '" + state.integration + "' not found.",
|
|
err,
|
|
);
|
|
},
|
|
});
|
|
}
|
|
|
|
function hide_integration_show_catalog() {
|
|
function show_catalog() {
|
|
$("html, body").animate({scrollTop: 0}, {duration: 200});
|
|
|
|
$(".integration-categories-dropdown").css("display", "");
|
|
$(".integrations .catalog").removeClass("hide");
|
|
$(".extra, #integration-main-text, #integration-search").css("display", "block");
|
|
adjust_font_sizing();
|
|
}
|
|
|
|
function hide_integration() {
|
|
$("#integration-instruction-block").css("display", "none");
|
|
$("#integration-instructions-group").css("display", "none");
|
|
$(".inner-content").css({padding: ""});
|
|
$("#integration-instruction-block .integration-lozenge").remove();
|
|
show_catalog();
|
|
}
|
|
|
|
hide_integration();
|
|
}
|
|
|
|
function get_state_from_path() {
|
|
const result = {...INITIAL_STATE};
|
|
result.query = state.query;
|
|
|
|
const parts = path_parts();
|
|
if (parts[1] === "doc" && INTEGRATIONS.get(parts[2])) {
|
|
result.integration = parts[2];
|
|
} else if (CATEGORIES.has(parts[1])) {
|
|
result.category = parts[1];
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
function render(next_state) {
|
|
const previous_state = {...state};
|
|
state = next_state;
|
|
|
|
if (previous_state.integration !== next_state.integration && next_state.integration !== null) {
|
|
hide_catalog_show_integration();
|
|
} else {
|
|
if (previous_state.integration !== next_state.integration) {
|
|
hide_integration_show_catalog();
|
|
}
|
|
|
|
if (previous_state.category !== next_state.category) {
|
|
update_categories();
|
|
update_integrations();
|
|
}
|
|
|
|
if (previous_state.query !== next_state.query) {
|
|
update_integrations();
|
|
}
|
|
|
|
$(".main").css("visibility", "visible");
|
|
}
|
|
}
|
|
|
|
function dispatch(action, payload) {
|
|
switch (action) {
|
|
case "CHANGE_CATEGORY":
|
|
render({...state, category: payload.category});
|
|
update_path();
|
|
break;
|
|
|
|
case "SHOW_INTEGRATION":
|
|
render({...state, integration: payload.integration});
|
|
update_path();
|
|
break;
|
|
|
|
case "HIDE_INTEGRATION":
|
|
render({...state, integration: null});
|
|
update_path();
|
|
break;
|
|
|
|
case "SHOW_CATEGORY":
|
|
render({...state, integration: null, category: payload.category});
|
|
update_path();
|
|
break;
|
|
|
|
case "UPDATE_QUERY":
|
|
render({...state, query: payload.query});
|
|
break;
|
|
|
|
case "LOAD_PATH":
|
|
render(get_state_from_path());
|
|
google_analytics.config({page_path: window.location.pathname});
|
|
break;
|
|
|
|
default:
|
|
blueslip.error("Invalid action dispatched on /integrations.");
|
|
break;
|
|
}
|
|
}
|
|
|
|
function toggle_categories_dropdown() {
|
|
const $dropdown_list = $(".integration-categories-dropdown .dropdown-list");
|
|
$dropdown_list.slideToggle(250);
|
|
}
|
|
|
|
function integration_events() {
|
|
$('#integration-search input[type="text"]').on("keypress", (e) => {
|
|
if (e.which === 13 && e.target.value !== "") {
|
|
for (const integration_element of $(".integration-lozenges").children()) {
|
|
const integration = $(integration_element).find(".integration-lozenge");
|
|
|
|
if ($(integration).css("display") !== "none") {
|
|
$(integration).closest("a")[0].click();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
$(".integration-categories-dropdown .dropdown-toggle").on("click", () => {
|
|
toggle_categories_dropdown();
|
|
});
|
|
|
|
$(".integration-instruction-block").on("click", "a .integration-category", (e) => {
|
|
e.preventDefault();
|
|
const category = $(e.target).data("category");
|
|
dispatch("SHOW_CATEGORY", {category});
|
|
});
|
|
|
|
$(".integrations a .integration-category").on("click", (e) => {
|
|
e.preventDefault();
|
|
const category = $(e.target).data("category");
|
|
dispatch("CHANGE_CATEGORY", {category});
|
|
toggle_categories_dropdown();
|
|
});
|
|
|
|
$(".integrations a .integration-lozenge").on("click", (e) => {
|
|
if (!$(e.target).closest(".integration-lozenge").hasClass("integration-create-your-own")) {
|
|
e.preventDefault();
|
|
const integration = $(e.target).closest(".integration-lozenge").data("name");
|
|
dispatch("SHOW_INTEGRATION", {integration});
|
|
}
|
|
});
|
|
|
|
$("a#integration-list-link span, a#integration-list-link i").on("click", (e) => {
|
|
e.preventDefault();
|
|
dispatch("HIDE_INTEGRATION");
|
|
});
|
|
|
|
// combine selector use for both focusing the integrations searchbar and adding
|
|
// the input event.
|
|
$(".integrations .searchbar input[type='text']").on("input", (e) => {
|
|
dispatch("UPDATE_QUERY", {query: e.target.value.toLowerCase()});
|
|
});
|
|
|
|
$(window).on("scroll", () => {
|
|
if (document.body.scrollTop > 330) {
|
|
$(".integration-categories-sidebar").addClass("sticky");
|
|
} else {
|
|
$(".integration-categories-sidebar").removeClass("sticky");
|
|
}
|
|
});
|
|
|
|
$(window).on("resize", () => {
|
|
adjust_font_sizing();
|
|
});
|
|
|
|
$(window).on("popstate", () => {
|
|
if (window.location.pathname.startsWith("/integrations")) {
|
|
dispatch("LOAD_PATH");
|
|
} else {
|
|
window.location = window.location.href;
|
|
}
|
|
});
|
|
}
|
|
|
|
// init
|
|
$(() => {
|
|
integration_events();
|
|
load_data();
|
|
dispatch("LOAD_PATH");
|
|
$(".integrations .searchbar input[type='text']").trigger("focus");
|
|
});
|