debian-mirror-gitlab/app/assets/javascripts/user_popovers.js

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

139 lines
3.5 KiB
JavaScript
Raw Normal View History

2019-02-15 15:39:39 +05:30
import Vue from 'vue';
2022-07-23 23:45:48 +05:30
import { debounce } from 'lodash';
2019-02-15 15:39:39 +05:30
import UsersCache from './lib/utils/users_cache';
import UserPopover from './vue_shared/components/user_popover/user_popover.vue';
2022-07-23 23:45:48 +05:30
import { USER_POPOVER_DELAY } from './vue_shared/components/user_popover/constants';
2019-02-15 15:39:39 +05:30
2021-03-08 18:12:59 +05:30
const removeTitle = (el) => {
2020-03-13 15:44:24 +05:30
// Removing titles so its not showing tooltips also
el.dataset.originalTitle = '';
el.setAttribute('title', '');
};
2021-03-08 18:12:59 +05:30
const getPreloadedUserInfo = (dataset) => {
2020-03-13 15:44:24 +05:30
const userId = dataset.user || dataset.userId;
const { username, name, avatarUrl } = dataset;
return {
userId,
username,
name,
avatarUrl,
};
2019-02-15 15:39:39 +05:30
};
/**
* Adds a UserPopover component to the body, hands over as much data as the target element has in data attributes.
* loads based on data-user-id more data about a user from the API and sets it on the popover
*/
2021-03-08 18:12:59 +05:30
const populateUserInfo = (user) => {
2020-03-13 15:44:24 +05:30
const { userId } = user;
return Promise.all([UsersCache.retrieveById(userId), UsersCache.retrieveStatusById(userId)]).then(
([userData, status]) => {
if (userData) {
Object.assign(user, {
2022-07-16 23:28:13 +05:30
id: userId,
2020-03-13 15:44:24 +05:30
avatarUrl: userData.avatar_url,
2021-04-17 20:07:23 +05:30
bot: userData.bot,
2020-03-13 15:44:24 +05:30
username: userData.username,
name: userData.name,
location: userData.location,
bio: userData.bio,
2020-04-22 19:07:51 +05:30
workInformation: userData.work_information,
2021-01-03 14:25:43 +05:30
websiteUrl: userData.website_url,
2021-09-30 23:02:18 +05:30
pronouns: userData.pronouns,
2021-11-18 22:05:49 +05:30
localTime: userData.local_time,
2022-07-16 23:28:13 +05:30
isFollowed: userData.is_followed,
2020-03-13 15:44:24 +05:30
loaded: true,
});
}
if (status) {
Object.assign(user, {
status,
});
}
return user;
},
);
};
2022-07-23 23:45:48 +05:30
function createPopover(el, user) {
removeTitle(el);
const preloadedUserInfo = getPreloadedUserInfo(el.dataset);
2020-03-13 15:44:24 +05:30
2022-07-23 23:45:48 +05:30
Object.assign(user, preloadedUserInfo);
2021-04-17 20:07:23 +05:30
2022-07-23 23:45:48 +05:30
if (preloadedUserInfo.userId) {
populateUserInfo(user);
2021-04-17 20:07:23 +05:30
}
2022-07-23 23:45:48 +05:30
const UserPopoverComponent = Vue.extend(UserPopover);
return new UserPopoverComponent({
propsData: {
target: el,
user,
show: true,
placement: el.dataset.placement || 'top',
},
});
}
2021-04-17 20:07:23 +05:30
2022-07-23 23:45:48 +05:30
function launchPopover(el, mountPopover) {
if (el.user) return;
2021-04-17 20:07:23 +05:30
2022-07-23 23:45:48 +05:30
const emptyUser = {
location: null,
bio: null,
workInformation: null,
status: null,
isFollowed: false,
loaded: false,
};
el.user = emptyUser;
el.addEventListener(
'mouseleave',
({ target }) => {
target.removeAttribute('aria-describedby');
},
{ once: true },
);
const popoverInstance = createPopover(el, emptyUser);
const { userId } = el.dataset;
popoverInstance.$on('follow', () => {
UsersCache.updateById(userId, { is_followed: true });
el.user.isFollowed = true;
});
popoverInstance.$on('unfollow', () => {
UsersCache.updateById(userId, { is_followed: false });
el.user.isFollowed = false;
});
mountPopover(popoverInstance);
2021-04-17 20:07:23 +05:30
}
2022-08-13 15:12:31 +05:30
const userLinkSelector = 'a.js-user-link[data-user], a.js-user-link[data-user-id]';
2020-03-13 15:44:24 +05:30
2022-07-23 23:45:48 +05:30
const getUserLinkNode = (node) => node.closest(userLinkSelector);
2021-04-17 20:07:23 +05:30
2022-07-23 23:45:48 +05:30
const lazyLaunchPopover = debounce((mountPopover, event) => {
const userLink = getUserLinkNode(event.target);
if (userLink) {
launchPopover(userLink, mountPopover);
}
}, USER_POPOVER_DELAY);
2020-03-13 15:44:24 +05:30
2022-07-23 23:45:48 +05:30
let hasAddedLazyPopovers = false;
export default function addPopovers(mountPopover = (instance) => instance.$mount()) {
if (!hasAddedLazyPopovers) {
document.addEventListener('mouseover', (event) => lazyLaunchPopover(mountPopover, event));
hasAddedLazyPopovers = true;
}
2021-04-17 20:07:23 +05:30
}