Merge of Insiders features tied to 'Black Pearl' funding goal

This commit is contained in:
squidfunk
2021-03-29 18:46:57 +02:00
parent 8677190f3f
commit ca3da9e3ca
51 changed files with 867 additions and 194 deletions

View File

@@ -32,7 +32,6 @@ import {
import { setSourceFacts, setSourceState } from "~/actions"
import { renderSourceFacts } from "~/templates"
import { digest } from "~/utilities"
import { Component } from "../../_"
import { SourceFacts, fetchSourceFacts } from "../facts"
@@ -75,14 +74,14 @@ export function watchSource(
el: HTMLAnchorElement
): Observable<Source> {
return fetch$ ||= defer(() => {
const data = sessionStorage.getItem(digest("__repo"))
const data = sessionStorage.getItem(__prefix("__source"))
if (data) {
return of<SourceFacts>(JSON.parse(data))
} else {
const value$ = fetchSourceFacts(el.href)
value$.subscribe(value => {
try {
sessionStorage.setItem(digest("__repo"), JSON.stringify(value))
sessionStorage.setItem(__prefix("__source"), JSON.stringify(value))
} catch (err) {
/* Uncritical, just swallow */
}
@@ -94,7 +93,7 @@ export function watchSource(
})
.pipe(
catchError(() => NEVER),
filter(facts => facts.length > 0),
filter(facts => Object.keys(facts).length > 0),
map(facts => ({ facts })),
shareReplay(1)
)

View File

@@ -29,10 +29,30 @@ import { fetchSourceFactsFromGitLab } from "../gitlab"
* Types
* ------------------------------------------------------------------------- */
/**
* Repository facts for repositories
*/
export interface RepositoryFacts {
stars?: number /* Number of stars */
forks?: number /* Number of forks */
version?: string /* Latest version */
}
/**
* Repository facts for organizations
*/
export interface OrganizationFacts {
repositories?: number /* Number of repositories */
}
/* ------------------------------------------------------------------------- */
/**
* Repository facts
*/
export type SourceFacts = string[]
export type SourceFacts =
| RepositoryFacts
| OrganizationFacts
/* ----------------------------------------------------------------------------
* Functions

View File

@@ -21,14 +21,24 @@
*/
import { Repo, User } from "github-types"
import { Observable } from "rxjs"
import { Observable, zip } from "rxjs"
import { defaultIfEmpty, map } from "rxjs/operators"
import { requestJSON } from "~/browser"
import { round } from "~/utilities"
import { SourceFacts } from "../_"
/* ----------------------------------------------------------------------------
* Helper types
* ------------------------------------------------------------------------- */
/**
* GitHub release (partial)
*/
interface Release {
tag_name: string /* Tag name */
}
/* ----------------------------------------------------------------------------
* Functions
* ------------------------------------------------------------------------- */
@@ -44,29 +54,42 @@ import { SourceFacts } from "../_"
export function fetchSourceFactsFromGitHub(
user: string, repo?: string
): Observable<SourceFacts> {
const url = typeof repo !== "undefined"
? `https://api.github.com/repos/${user}/${repo}`
: `https://api.github.com/users/${user}`
return requestJSON<Repo & User>(url)
.pipe(
map(data => {
if (typeof repo !== "undefined") {
const url = `https://api.github.com/repos/${user}/${repo}`
return zip(
/* GitHub repository */
if (typeof repo !== "undefined") {
const { stargazers_count, forks_count }: Repo = data
return [
`${round(stargazers_count!)} Stars`,
`${round(forks_count!)} Forks`
]
/* Fetch version */
requestJSON<Release>(`${url}/releases/latest`)
.pipe(
map(release => ({
version: release.tag_name
})),
defaultIfEmpty({})
),
/* GitHub user/organization */
} else {
const { public_repos }: User = data
return [
`${round(public_repos!)} Repositories`
]
}
}),
defaultIfEmpty([])
/* Fetch stars and forks */
requestJSON<Repo>(url)
.pipe(
map(info => ({
stars: info.stargazers_count,
forks: info.forks_count
})),
defaultIfEmpty({})
)
)
.pipe(
map(([release, info]) => ({ ...release, ...info }))
)
/* User or organization */
} else {
const url = `https://api.github.com/repos/${user}`
return requestJSON<User>(url)
.pipe(
map(info => ({
repositories: info.public_repos
})),
defaultIfEmpty({})
)
}
}

View File

@@ -25,7 +25,6 @@ import { Observable } from "rxjs"
import { defaultIfEmpty, map } from "rxjs/operators"
import { requestJSON } from "~/browser"
import { round } from "~/utilities"
import { SourceFacts } from "../_"
@@ -47,10 +46,10 @@ export function fetchSourceFactsFromGitLab(
const url = `https://${base}/api/v4/projects/${encodeURIComponent(project)}`
return requestJSON<ProjectSchema>(url)
.pipe(
map(({ star_count, forks_count }) => ([
`${round(star_count)} Stars`,
`${round(forks_count)} Forks`
])),
defaultIfEmpty([])
map(({ star_count, forks_count }) => ({
stars: star_count,
forks: forks_count
})),
defaultIfEmpty({})
)
}