Add github provider

This commit is contained in:
Rodrigo Pombo 2019-02-18 01:53:07 -03:00
parent dd596040fc
commit 8fe1e9cd08
8 changed files with 65 additions and 154 deletions

View File

@ -1,6 +1,5 @@
import React, { useState, useEffect } from "react";
import { getLanguage, loadLanguage } from "./language-detector";
import { auth, isLoggedIn, getCommits } from "./github";
export function Center({ children }) {
return (
@ -29,7 +28,7 @@ export function Loading({ repo, path }) {
);
}
export function Error({ error }) {
export function Error({ error, gitProvider }) {
if (error.status === 403) {
return (
<Center>
@ -37,7 +36,7 @@ export function Error({ error }) {
GitHub API rate limit exceeded for your IP (60 requests per hour).
</p>
<p>Sign in with GitHub for more:</p>
<GitHubButton onClick={login} />
<GitHubButton onClick={gitProvider.logIn} />
</Center>
);
}
@ -46,10 +45,10 @@ export function Error({ error }) {
return (
<Center>
<p>File not found.</p>
{!isLoggedIn() && (
{gitProvider.isLoggedIn && !gitProvider.isLoggedIn() && (
<React.Fragment>
<p>Is it from a private repo? Sign in with GitHub:</p>
<GitHubButton onClick={login} />
<GitHubButton onClick={gitProvider.login} />
</React.Fragment>
)}
</Center>
@ -127,37 +126,8 @@ export function useLanguageLoader(path) {
}, [path]);
}
export function useCommitsFetcher({ repo, sha, path }) {
return useLoader(async () => getCommits(repo, sha, path), [repo, sha, path]);
}
export function useDocumentTitle(title) {
useEffect(() => {
document.title = title;
}, [title]);
}
export function getUrlParams() {
const [
,
owner,
reponame,
action,
sha,
...paths
] = window.location.pathname.split("/");
if (action !== "commits" && action !== "blob") {
return [];
}
return [owner + "/" + reponame, sha, "/" + paths.join("/")];
}
function login() {
auth()
.then(data => {
window.location.reload(false);
})
.catch(console.error);
}

View File

@ -8,7 +8,7 @@ import {
Error,
useLoader
} from "./app-helpers";
import getGitProvider from "./providers/providers";
import getGitProvider from "./git-providers/providers";
export default function App() {
const gitProvider = getGitProvider();
@ -36,7 +36,7 @@ function InnerApp({ gitProvider }) {
const error = langError || commitsError;
if (error) {
return <Error error={error} />;
return <Error error={error} gitProvider={gitProvider} />;
}
if (loading) {
@ -44,7 +44,7 @@ function InnerApp({ gitProvider }) {
}
if (!commits.length) {
return <Error error={{ status: 404 }} />;
return <Error error={{ status: 404 }} gitProvider={gitProvider} />;
}
return <History commits={commits} language={lang} />;

View File

@ -7,7 +7,7 @@ function getHeaders() {
return token ? { Authorization: `bearer ${token}` } : {};
}
export function isLoggedIn() {
function isLoggedIn() {
return !!window.localStorage.getItem(TOKEN_KEY);
}
@ -25,7 +25,35 @@ async function getContent(repo, sha, path) {
return { content, url: contentJson.html_url };
}
export async function getCommits(repo, sha, path, top = 10) {
function getUrlParams() {
const [
,
owner,
reponame,
action,
sha,
...paths
] = window.location.pathname.split("/");
if (action !== "commits" && action !== "blob") {
return [];
}
return [owner + "/" + reponame, sha, "/" + paths.join("/")];
}
function getPath() {
const [, , path] = getUrlParams();
return path;
}
function showLanding() {
const [repo, ,] = getUrlParams();
return !repo;
}
async function getCommits(last = 10) {
const [repo, sha, path] = getUrlParams();
const commitsResponse = await fetch(
`https://api.github.com/repos/${repo}/commits?sha=${sha}&path=${path}`,
{ headers: getHeaders() }
@ -36,7 +64,7 @@ export async function getCommits(repo, sha, path, top = 10) {
const commitsJson = await commitsResponse.json();
const commits = commitsJson
.slice(0, top)
.slice(0, last)
.map(commit => ({
sha: commit.sha,
date: new Date(commit.commit.author.date),
@ -64,20 +92,29 @@ export async function getCommits(repo, sha, path, top = 10) {
return commits;
}
export function auth() {
return new Promise((resolve, reject) => {
var authenticator = new netlify({
site_id: "ccf3a0e2-ac06-4f37-9b17-df1dd41fb1a6"
});
authenticator.authenticate({ provider: "github", scope: "repo" }, function(
err,
data
) {
if (err) {
reject(err);
}
window.localStorage.setItem(TOKEN_KEY, data.token);
resolve(data);
});
function logIn() {
// return new Promise((resolve, reject) => {
var authenticator = new netlify({
site_id: "ccf3a0e2-ac06-4f37-9b17-df1dd41fb1a6"
});
authenticator.authenticate({ provider: "github", scope: "repo" }, function(
err,
data
) {
if (err) {
console.error(err);
return;
}
window.localStorage.setItem(TOKEN_KEY, data.token);
window.location.reload(false);
});
// });
}
export default {
showLanding,
getPath,
getCommits,
logIn,
isLoggedIn
};

View File

@ -1,4 +1,5 @@
import cliProvider from "./cli-provider";
import githubProvider from "./github-provider";
export default function getGitProvider() {
switch (process.env.REACT_APP_GIT_PROVIDER) {
@ -7,6 +8,6 @@ export default function getGitProvider() {
case "vscode":
return null;
default:
return null;
return githubProvider;
}
}

View File

@ -1,6 +1,5 @@
import React from "react";
import demo from "./demo.gif";
import { Center } from "./app-helpers";
export default function Landing() {
const url = `${window.location.protocol}//${
@ -74,6 +73,7 @@ export default function Landing() {
<img
src="https://opencollective.com/git-history/donate/button.png?color=white"
width="300"
alt="donate"
/>
</a>
</div>

View File

@ -1,88 +0,0 @@
import netlify from "netlify-auth-providers";
import { Provider } from "./provider";
const TOKEN_KEY = "github-token";
function getHeaders() {
const token = window.localStorage.getItem(TOKEN_KEY);
return token ? { Authorization: `bearer ${token}` } : {};
}
async function getContent(repo, sha, path) {
const contentResponse = await fetch(
`https://api.github.com/repos/${repo}/contents${path}?ref=${sha}`,
{ headers: getHeaders() }
);
if (!contentResponse.ok) {
throw contentResponse;
}
const contentJson = await contentResponse.json();
const content = Base64.decode(contentJson.content);
return { content, url: contentJson.html_url };
}
const githubProvider: Provider = {
isLoggedIn: () => {
return !!window.localStorage.getItem(TOKEN_KEY);
},
logIn: () => {
return new Promise((resolve, reject) => {
const authenticator: any = new netlify({
site_id: "ccf3a0e2-ac06-4f37-9b17-df1dd41fb1a6"
});
authenticator.authenticate(
{ provider: "github", scope: "repo" },
(err, data) => {
if (err) {
reject(err);
}
window.localStorage.setItem(TOKEN_KEY, data.token);
resolve(data);
}
);
});
},
getCommits: async (path, repo, sha) => {
const commitsResponse = await fetch(
`https://api.github.com/repos/${repo}/commits?sha=${sha}&path=${path}`,
{ headers: getHeaders() }
);
if (!commitsResponse.ok) {
throw commitsResponse;
}
const commitsJson = await commitsResponse.json();
const commits = commitsJson
.slice(0, top)
.map(commit => ({
sha: commit.sha,
date: new Date(commit.commit.author.date),
author: {
login: commit.author
? commit.author.login
: commit.commit.author.name,
avatar: commit.author
? commit.author.avatar_url
: "https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png"
},
commitUrl: commit.html_url,
message: commit.commit.message
}))
.sort(function(a, b) {
return a.date - b.date;
});
await Promise.all(
commits.map(async commit => {
const info = await getContent(repo, commit.sha, path);
commit.content = info.content;
commit.fileUrl = info.url;
})
);
return commits;
}
};
export default githubProvider;

View File

@ -1,9 +0,0 @@
type Commit = {
message: string;
};
export interface Provider {
isLoggedIn?: () => boolean;
logIn?: () => Promise<null>;
getCommits: (path: string, repo?: string, sha?: string) => Promise<Commit[]>;
}