mirror of
https://github.com/pomber/git-history.git
synced 2024-11-22 23:13:20 +03:00
Add github provider
This commit is contained in:
parent
dd596040fc
commit
8fe1e9cd08
@ -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);
|
||||
}
|
||||
|
@ -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} />;
|
||||
|
@ -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
|
||||
};
|
@ -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;
|
||||
}
|
||||
}
|
@ -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>
|
||||
|
@ -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;
|
@ -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[]>;
|
||||
}
|
Loading…
Reference in New Issue
Block a user