Skip to content

Commit

Permalink
Make clicking an external link in Firefox close the popup (#38)
Browse files Browse the repository at this point in the history
* Update external links so that they close the popup in Firefox

* Make PR deep links actual link elements that will close the popup
  • Loading branch information
jdgarcia authored May 14, 2024
1 parent 19eb905 commit 7f387d2
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 43 deletions.
9 changes: 0 additions & 9 deletions src/deepLink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,12 +229,3 @@ export const getGitKrakenDeepLinkUrl = (provider: FocusViewSupportedProvider, ur

return getGKDotDevLinkUrl(redirectUrl);
};

export const openGitKrakenDeepLink = (provider: FocusViewSupportedProvider, url: string | null) => {
const deepLink = getGitKrakenDeepLinkUrl(provider, url);
if (!deepLink) {
return;
}

window.open(deepLink, '_blank');
};
21 changes: 9 additions & 12 deletions src/popup/components/ConnectAProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,41 @@
import React from 'react';
import { GKDotDevUrl } from '../../shared';
import { ExternalLink } from './ExternalLink';

export const ConnectAProvider = () => {
return (
<div className="connect-provider-container">
<div className="connect-provider-prompt text-center">
<div className="text-2xl bold">Connect an integration to see all of your pull requests</div>
<div className="provider-buttons">
<a
<ExternalLink
className="provider-button text-sm text-secondary"
href={`${GKDotDevUrl}/settings/integrations?connect=github`}
target="_blank"
>
<img src="img/github-color.svg" height={24} />
<div>GitHub</div>
</a>
<a
</ExternalLink>
<ExternalLink
className="provider-button text-sm text-secondary"
href={`${GKDotDevUrl}/settings/integrations?connect=gitlab`}
target="_blank"
>
<img src="img/gitlab-color.svg" height={24} />
<div>GitLab</div>
</a>
<a
</ExternalLink>
<ExternalLink
className="provider-button text-sm text-secondary"
href={`${GKDotDevUrl}/settings/integrations?connect=bitbucket`}
target="_blank"
>
<img src="img/bitbucket-color.svg" height={24} />
<div>Bitbucket</div>
</a>
<a
</ExternalLink>
<ExternalLink
className="provider-button text-sm text-secondary"
href={`${GKDotDevUrl}/settings/integrations?connect=azure`}
target="_blank"
>
<img src="img/azuredevops-color.svg" height={24} />
<div>Azure DevOps</div>
</a>
</ExternalLink>
</div>
<div className="text-sm text-secondary italic">
*Only cloud-hosted providers are currently supported.
Expand Down
42 changes: 42 additions & 0 deletions src/popup/components/ExternalLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from 'react';
import { tabs } from 'webextension-polyfill';

type ExternalLinkProps = {
children: React.ReactNode;
className?: string;
href?: string;
onClick?: () => any;
title?: string;
};

export const ExternalLink = ({ children, className, href, onClick, title }: ExternalLinkProps) => {
return (
<a
className={className}
href={href}
rel="noreferrer noopener"
target="_blank"
title={title}
onClick={async e => {
// Opening external links in Firefox will not cause the popup to automatically close,
// so we must manually close it.

// Closing the popup window before the link has finished opening will cause Firefox to open
// the link in a new window instead of in a new tab. In order to prevent this, we manually
// open the link in a new tab and await that, then close the popup window afterwards.
e.preventDefault();

if (onClick) {
await onClick();
}
if (href) {
await tabs.create({ url: href });
}

window.close();
}}
>
{children}
</a>
);
};
26 changes: 10 additions & 16 deletions src/popup/components/FocusView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { GitProviderUtils } from '@gitkraken/provider-apis';
import { useQueryClient } from '@tanstack/react-query';
import React, { useEffect, useMemo, useState } from 'react';
import { storage } from 'webextension-polyfill';
import { openGitKrakenDeepLink } from '../../deepLink';
import { getGitKrakenDeepLinkUrl } from '../../deepLink';
import { ProviderMeta } from '../../providers';
import { GKDotDevUrl } from '../../shared';
import type {
Expand All @@ -12,6 +12,7 @@ import type {
} from '../../types';
import { useFocusViewConnectedProviders, useFocusViewDataQuery, usePullRequestDraftCountsQuery } from '../hooks';
import { ConnectAProvider } from './ConnectAProvider';
import { ExternalLink } from './ExternalLink';

type PullRequestRowProps = {
userId: string;
Expand All @@ -22,17 +23,17 @@ type PullRequestRowProps = {

const PullRequestRow = ({ userId, pullRequest, provider, draftCount = 0 }: PullRequestRowProps) => {
const queryClient = useQueryClient();
const deepLinkUrl = getGitKrakenDeepLinkUrl(provider, pullRequest.url);

return (
<>
<div className="pull-request">
<div className="pull-request-title truncate">{pullRequest.title}</div>
<div className="repository-name text-secondary truncate">{pullRequest.repository.name}</div>
<div className="pull-request-number">
<a
<ExternalLink
className="text-link"
href={pullRequest.url || undefined}
target="_blank"
onClick={() => {
// Since there is a decent chance that the PR will be acted upon after the user clicks on it,
// mark the focus view data as stale so that it will be refetched when the user returns.
Expand All @@ -41,32 +42,25 @@ const PullRequestRow = ({ userId, pullRequest, provider, draftCount = 0 }: PullR
title={`View pull request on ${ProviderMeta[provider].name}`}
>
#{pullRequest.number}
</a>
</ExternalLink>
</div>
{pullRequest.url && (
<a
href="#"
onClick={() => {
openGitKrakenDeepLink(provider, pullRequest.url);
}}
title="Open with GitKraken"
>
{deepLinkUrl && (
<ExternalLink href={deepLinkUrl} title="Open with GitKraken">
<i className="fa-brands fa-gitkraken icon text-link text-lg" />
</a>
</ExternalLink>
)}
</div>
{draftCount > 0 && (
<a
<ExternalLink
className="pr-drafts-badge text-disabled"
href={`${GKDotDevUrl}/drafts/suggested-change/${encodeURIComponent(
btoa(pullRequest.uniqueId),
)}?source=browserExtension`}
target="_blank"
title={`View code suggestion${draftCount === 1 ? '' : 's'} on gitkraken.dev`}
>
<i className="fa-regular fa-message-code icon" />
Code Suggestion{draftCount === 1 ? '' : 's'}
</a>
</ExternalLink>
)}
</>
);
Expand Down
5 changes: 3 additions & 2 deletions src/popup/components/SignedIn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { logoutUser } from '../../gkApi';
import type { PermissionsRequest } from '../../permissions-helper';
import { GKDotDevUrl } from '../../shared';
import type { User } from '../../types';
import { ExternalLink } from './ExternalLink';
import { FocusView } from './FocusView';
import { RequestPermissionsBanner } from './RequestPermissionsBanner';

Expand Down Expand Up @@ -45,9 +46,9 @@ export const SignedIn = ({ permissionsRequest, user }: { permissionsRequest?: Pe
<div>{user.name || user.username}</div>
<div className="text-sm text-secondary">{user.email}</div>
</div>
<a href={GKDotDevUrl} target="_blank" title="Open gitkraken.dev">
<ExternalLink href={GKDotDevUrl} title="Open gitkraken.dev">
<i className="fa-regular fa-arrow-up-right-from-square icon text-lg" />
</a>
</ExternalLink>
</div>
<button className="icon-btn" onClick={onSignOutClick} title="Sign out">
<i className="fa-regular fa-right-from-bracket icon text-lg" />
Expand Down
9 changes: 5 additions & 4 deletions src/popup/components/SignedOut.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import type { PermissionsRequest } from '../../permissions-helper';
import { GKDotDevUrl } from '../../shared';
import { ExternalLink } from './ExternalLink';
import { RequestPermissionsBanner } from './RequestPermissionsBanner';

export const SignedOut = ({ permissionsRequest }: { permissionsRequest?: PermissionsRequest }) => {
Expand All @@ -9,13 +10,13 @@ export const SignedOut = ({ permissionsRequest }: { permissionsRequest?: Permiss
{permissionsRequest && <RequestPermissionsBanner permissionsRequest={permissionsRequest} />}
<div className="sign-in-prompt">
<div className="text-2xl bold">Sign in to view your Pull Requests</div>
<a className="sign-in-link text-sm text-secondary bg-02" href={`${GKDotDevUrl}/login`} target="_blank">
<ExternalLink className="sign-in-link text-sm text-secondary bg-02" href={`${GKDotDevUrl}/login`}>
<img src="img/gk-logo-36.svg" height={36} width={36} />
Sign in with GitKraken
</a>
<a className="text-link" href={`${GKDotDevUrl}/register`} target="_blank">
</ExternalLink>
<ExternalLink className="text-link" href={`${GKDotDevUrl}/register`}>
Create an account
</a>
</ExternalLink>
</div>
</div>
);
Expand Down

0 comments on commit 7f387d2

Please sign in to comment.