Skip to content

Commit

Permalink
refactor: a basic demo showing how to use native popover to present o…
Browse files Browse the repository at this point in the history
…ur content
  • Loading branch information
tyn1998 committed Apr 24, 2024
1 parent 4a09f0d commit 22c91ff
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 44 deletions.
92 changes: 51 additions & 41 deletions src/pages/ContentScripts/features/repo-star-tooltip/index.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
import React from 'react';
import { render, Container } from 'react-dom';
import elementReady from 'element-ready';
import $ from 'jquery';

import features from '../../../../feature-manager';
import getGithubTheme from '../../../../helpers/get-github-theme';
import View from './view';
import { checkLogined } from '../../../../helpers/get-developer-info';
import elementReady from 'element-ready';
import {
getRepoName,
hasRepoContainerHeader,
isPublicRepoWithMeta,
} from '../../../../helpers/get-repo-info';
import { getStars } from '../../../../api/repo';
import View from './view';
import { RepoMeta, metaStore } from '../../../../api/common';
import { checkLogined } from '../../../../helpers/get-developer-info';

const githubTheme = getGithubTheme();
import React from 'react';
import { render, Container, unmountComponentAtNode } from 'react-dom';
import $ from 'jquery';

const featureId = features.getFeatureID(import.meta.url);
let repoName: string;
let stars: any;
Expand All @@ -33,44 +31,56 @@ const renderTo = (container: Container) => {
const init = async (): Promise<void> => {
repoName = getRepoName();
await getData();

const isLogined = checkLogined();
const selector = isLogined
const starButtonSelector = isLogined
? 'button[data-ga-click*="star button"]'
: 'a[data-hydro-click*="star button"]';
await elementReady(selector);
const attributes = {
'data-tip': '',
'data-for': 'star-tooltip',
'data-class': `floating-window ${githubTheme}`,
'data-place': 'left',
'data-effect': 'solid',
'data-delay-hide': 500,
'data-delay-show': 1000,
style: { color: githubTheme === 'light' ? '#24292f' : '#c9d1d9' },
'data-text-color': githubTheme === 'light' ? '#24292F' : '#C9D1D9',
'data-background-color': githubTheme === 'light' ? 'white' : '#161B22',
};
$(selector).attr(attributes);
await elementReady(starButtonSelector);
const $starButton = $(starButtonSelector);
// get the position of the star button
const offset = $starButton.offset();
if (!offset) {
return;
}
const { top, left } = offset;
const width = $starButton.outerWidth();
const height = $starButton.outerHeight();
if (!height || !width) {
return;
}

const container = document.createElement('div');
container.id = featureId;
renderTo(container);
(await elementReady('#repository-container-header'))?.append(container);
$starButton[0].addEventListener('mouseenter', () => {
const popoverContainerSelector = 'div.Popover';
const popoverContentSelector = 'div.Popover-message';
const $popoverContent = $(popoverContentSelector);
const contentWidth = $popoverContent.outerWidth();
if (!contentWidth) {
return;
}
const $popoverContainer = $(popoverContainerSelector);
$popoverContainer.css('display', 'block');
$popoverContainer.css('top', `${top + height + 10}px`);
$popoverContent.removeClass('Popover-message--bottom-left');
$popoverContent.removeClass('Popover-message--large');
$popoverContent.css('width', '270px');
$popoverContainer.css('left', `${left - (contentWidth - width) / 2}px`);
$popoverContent.addClass('Popover-message--top-middle');
renderTo($popoverContent[0]);
});
$starButton[0].addEventListener('mouseleave', () => {
const popoverContainerSelector = 'div.Popover';
const popoverContentSelector = 'div.Popover-message';
const $popoverContent = $(popoverContentSelector);
const $popoverContainer = $(popoverContainerSelector);
$popoverContent.addClass('Popover-message--large');
$popoverContainer.css('display', 'none');
if ($popoverContent.children().length > 0) {
unmountComponentAtNode($popoverContent[0]);
}
});
};

const restore = async () => {
// Clicking another repo link in one repo will trigger a turbo:visit,
// so in a restoration visit we should be careful of the current repo.
if (repoName !== getRepoName()) {
repoName = getRepoName();
await getData();
}
// Ideally, we should do nothing if the container already exists. But after a tubor
// restoration visit, tooltip cannot be triggered though it exists in DOM tree. One
// way to solve this is to rerender the view to the container. At least this way works.
renderTo($(`#${featureId}`)[0]);
};
const restore = async () => {};

features.add(featureId, {
asLongAs: [isPublicRepoWithMeta, hasRepoContainerHeader],
Expand Down
5 changes: 2 additions & 3 deletions src/pages/ContentScripts/features/repo-star-tooltip/view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import optionsStorage, {
defaults,
} from '../../../../options-storage';
import generateDataByMonth from '../../../../helpers/generate-data-by-month';
import ReactTooltip from 'react-tooltip';
import StarChart from './StarChart';
import { RepoMeta } from '../../../../api/common';

Expand All @@ -30,7 +29,7 @@ const View = ({ stars, meta }: Props): JSX.Element | null => {
if (!stars) return null;

return (
<ReactTooltip id="star-tooltip" clickable={true}>
<>
<div className="chart-title">
{getMessageByLocale('star_popup_title', options.locale)}
</div>
Expand All @@ -40,7 +39,7 @@ const View = ({ stars, meta }: Props): JSX.Element | null => {
height={130}
data={generateDataByMonth(stars, meta.updatedAt)}
/>
</ReactTooltip>
</>
);
};

Expand Down

0 comments on commit 22c91ff

Please sign in to comment.