Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add lock for private orgs on own profile #1490

Merged
merged 14 commits into from
Sep 11, 2018
1 change: 1 addition & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ GitHub Enterprise is also supported. More info in the options.
- [Review counts are shown and colored in PR lists.](https://user-images.githubusercontent.com/1402241/33474535-a814ee78-d6ad-11e7-8f08-a8b72799e376.png)
- [All available keyboard shortcuts are shown in the help modal.](https://user-images.githubusercontent.com/29176678/36999174-9f07d33e-20bf-11e8-83e3-b3a9908a4b5f.png) *(<kbd>?</kbd> hotkey)*
- [Followers you know are shown on profile pages.](https://user-images.githubusercontent.com/2906365/42009293-b1503f62-7a57-11e8-88f5-9c2fb3651a14.png)
- [Private organizations are marked when viewing your own profile.](https://user-images.githubusercontent.com/6775216/44633467-d5dcc900-a959-11e8-9116-e6b0ffef66af.png)

### Declutter

Expand Down
7 changes: 7 additions & 0 deletions source/content.css
Original file line number Diff line number Diff line change
Expand Up @@ -996,3 +996,10 @@ body > .footer li a {
padding-top: 4px !important;
padding-bottom: 4px !important;
}

.profile-org-private-lock {
pointer-events: none;
position: absolute;
top: 15px;
left: 20px;
}
5 changes: 5 additions & 0 deletions source/content.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ import hideCommentsFaster from './features/hide-comments-faster';
import linkifyCommitSha from './features/linkify-commit-sha';
import hideIssueListAutocomplete from './features/hide-issue-list-autocomplete';
import setDefaultRepositoriesTypeToSources from './features/set-default-repositories-type-to-sources';
import markPrivateOrgs from './features/mark-private-orgs';

import * as pageDetect from './libs/page-detect';
import {safeElementReady, enableFeature, safeOnAjaxedPages, injectCustomCSS} from './libs/utils';
Expand Down Expand Up @@ -306,6 +307,10 @@ function ajaxedPagesHandler() {
enableFeature(setDefaultRepositoriesTypeToSources);
}

if (pageDetect.isOwnUserProfile()) {
enableFeature(markPrivateOrgs);
}

if (pageDetect.isPRCommit()) {
enableFeature(linkifyCommitSha);
}
Expand Down
41 changes: 41 additions & 0 deletions source/features/mark-private-orgs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {h} from 'dom-chef';
import select from 'select-dom';
import {getUsername} from '../libs/utils';
import * as icons from '../libs/icons';
import api from '../libs/api';

export default async function () {
// List public orgs
const publicOrgs = [];
const orgDataList = await api(`users/${getUsername()}/orgs`);
if (!orgDataList) {
return;
}
for (const orgData of orgDataList) {
publicOrgs.push(`/${orgData.login}`);
}

const userContainer = select('[itemtype="http://schema.org/Person"]');
if (!userContainer) {
return;
}

// Find all org avatars
const orgAvatars = select.all('[itemprop="follows"]', userContainer);
for (const orgAvatar of orgAvatars) {
// Check if org is private
const orgPath = orgAvatar.getAttribute('href');
if (!orgPath) {
continue;
}

// Display the lock icon on private orgs
if (!publicOrgs.includes(orgPath)) {
orgAvatar.append(
<span class="profile-org-private-lock">
{icons.privateLockFilled(15)}
</span>
);
}
}
}
10 changes: 10 additions & 0 deletions source/libs/icons.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions source/libs/page-detect.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
/* eslint-disable unicorn/prefer-starts-ends-with, The tested var might not be a string */

import {check as isReserved} from 'github-reserved-names';
import {getUsername} from './utils';

// Drops leading and trailing slash to avoid /\/?/ everywhere
export const getCleanPathname = () => location.pathname.replace(/^[/]|[/]$/g, '');
Expand Down Expand Up @@ -107,3 +108,5 @@ export const isSingleFile = () => /^blob\//.test(getRepoPath());
export const isTrending = () => location.pathname.startsWith('/trending');

export const isUserProfile = () => Boolean(getCleanPathname()) && !isGist() && !isReserved(getCleanPathname()) && !getCleanPathname().includes('/');

export const isOwnUserProfile = () => isUserProfile() && getCleanPathname().startsWith(getUsername());
1 change: 1 addition & 0 deletions test/copy-markdown.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import test from 'ava';
import './fixtures/globals';
import {stripIndent} from 'common-tags';
import {getSmarterMarkdown} from '../source/features/copy-markdown';

Expand Down
14 changes: 14 additions & 0 deletions test/fixtures/globals.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Window from './window';

global.window = new Window();
global.location = window.location;
global.document = {
addEventListener: () => {}
};
global.chrome = {
storage: {
sync: {
get: () => {}
}
}
};
3 changes: 3 additions & 0 deletions test/fixtures/window.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ const {URL} = require('url');

function WindowMock(initialURI = 'https://github.com') {
this.location = new URL(initialURI);
this.navigator = {
platform: "test"
}
}

module.exports = WindowMock;
6 changes: 1 addition & 5 deletions test/page-detect.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import test from 'ava';
import './fixtures/globals';
import * as pageDetect from '../source/libs/page-detect';
import Window from './fixtures/window';

global.window = new Window();
global.location = window.location;
global.document = {};

function urlMatcherMacro(t, detectFn, shouldMatch = [], shouldNotMatch = []) {
for (const url of shouldMatch) {
Expand Down
1 change: 1 addition & 0 deletions test/searchable-words.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import test from 'ava';
import './fixtures/globals';
sindresorhus marked this conversation as resolved.
Show resolved Hide resolved
import {getSearchableWords as fn} from '../source/features/display-issue-suggestions';

test('Searchable words filter', t => {
Expand Down