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 theme functionality #3

Merged
merged 2 commits into from
Jul 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
- [Top bundles](#top-bundles)
- [By vendor](#by-vendor)
- [By maintainer](#by-maintainer)
- [Themes](#themes)
- [Caching](#caching)

## Top bundles
Expand All @@ -43,5 +44,17 @@ Retrieves the top bundles for the given maintainer from the given vendor
![Packagist Top Bundles](https://github-readme-packagist-stats.vercel.app/api/packagist/card?vendor=exampleOrganization&maintainer=agonyz)
```

## Themes
You can use different themes for the cards
- How to use:
```markdown
/api/packagist/card?vendor={your-packagist-user}&theme=dark
```
- Example:
```markdown
![Packagist Top Bundles](https://github-readme-packagist-stats.vercel.app/api/packagist/card?vendor=agonyz&theme=dark)
```
![Packagist Top Bundles](https://github-readme-packagist-stats.vercel.app/api/packagist/card?vendor=agonyz&theme=dark)

## Caching
- In order to not overuse the packagist api a cache time of `12 hours` was implemented.
79 changes: 37 additions & 42 deletions src/routes/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,52 +15,47 @@ class MainRouter {
const router: Router = Router();

// main route
router.get(
'/api/packagist/card',
async (req: Request, res: Response) => {
const vendor: string | null = req.query.vendor as string ?? null;
const maintainer: string | null = req.query.maintainer as string ?? null;

// throw error if vendor is missing
if(!vendor) {
return res
.status(400)
.send(
'No vendor was given in the request.'
);
}

// check if the response is already cached
if (req.headers['x-vercel-cache'] === 'HIT') {
res.status(304).send();
return;
}

const packagistData = await this.packagistService.getPackagistData(
vendor,
maintainer
);
router.get('/api/packagist/card', async (req: Request, res: Response) => {
const vendor: string | null = (req.query.vendor as string) ?? null;
const maintainer: string | null =
(req.query.maintainer as string) ?? null;
const theme: string | null = (req.query.theme as string) ?? null;

// throw error if vendor is missing
if (!vendor) {
return res.status(400).send('No vendor was given in the request.');
}

if (!packagistData) {
return res
.status(400)
.send(
'Could not find packages for the given vendor or the fetch request failed.'
);
}
// log request information - may handle it in a helper function
console.log({ vendor });
console.log({ maintainer });

// log request information - may handle it in a helper function
console.log({vendor});
console.log({maintainer});
// check if the response is already cached
if (req.headers['x-vercel-cache'] === 'HIT') {
res.status(304).send();
return;
}

// set cache control headers for successful response (12 hours)
res.set('Cache-Control', 'public, max-age=43200');
res.set('Content-Type', 'image/svg+xml');
res.send(
this.cardService.createCard(packagistData, vendor, maintainer)
);
const packagistData = await this.packagistService.getPackagistData(
vendor,
maintainer
);

if (!packagistData) {
return res
.status(400)
.send(
'Could not find packages for the given vendor or the fetch request failed.'
);
}
);

// set cache control headers for successful response (12 hours)
res.set('Cache-Control', 'public, max-age=43200');
res.set('Content-Type', 'image/svg+xml');
res.send(
this.cardService.createCard(packagistData, vendor, maintainer, theme)
);
});
return router;
}
}
Expand Down
16 changes: 8 additions & 8 deletions src/services/card.service.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { Package } from '@agonyz/packagist-api-client/lib/interfaces';
const { createSVGWindow } = require('svgdom');
const d3 = require('d3-node');
import { cardCss } from '../styles/card';
import { ThemeService } from './theme.service';

/* eslint-disable @typescript-eslint/no-explicit-any */
export class CardService {
createCard(
bundles: Package[],
vendor: string,
maintainer: string | null
maintainer: string | null,
theme: string | null
): string {
// if maintainer is set, replace the vendor
if (maintainer) {
Expand All @@ -21,8 +22,8 @@ export class CardService {
const d3n = new d3({ window, document });
const svg = d3n.createSVG(svgWidth, svgHeight);

// add stylesheet
svg.append('style').text(cardCss);
// add theme
svg.append('style').text(ThemeService.getStyleContent(theme));

// create main card
this.createMainCard(svg, svgHeight, svgWidth);
Expand Down Expand Up @@ -118,8 +119,7 @@ export class CardService {
.attr('height', 55)
.attr('x', 30)
.attr('y', startY)
.attr('class', 'bundle-card')
.style('fill', '#fff');
.attr('class', 'bundle-card');
const bundleName = svg
.append('text')
.attr('x', 40)
Expand Down Expand Up @@ -151,15 +151,15 @@ export class CardService {
'd',
'M27.414 19.414l-10 10c-0.781 0.781-2.047 0.781-2.828 0l-10-10c-0.781-0.781-0.781-2.047 0-2.828s2.047-0.781 2.828 0l6.586 6.586v-19.172c0-1.105 0.895-2 2-2s2 0.895 2 2v19.172l6.586-6.586c0.39-0.39 0.902-0.586 1.414-0.586s1.024 0.195 1.414 0.586c0.781 0.781 0.781 2.047 0 2.828z'
)
.attr('class', 'downloads')
.attr('class', 'download-icon')
.attr('transform', `translate(368, ${startY + 8}), scale(0.40)`);
const starIcon = svg
.append('path')
.attr(
'd',
'M32 12.408l-11.056-1.607-4.944-10.018-4.944 10.018-11.056 1.607 8 7.798-1.889 11.011 9.889-5.199 9.889 5.199-1.889-11.011 8-7.798z'
)
.attr('class', 'stars')
.attr('class', 'star-icon')
.attr('transform', `translate(368, ${startY + 28}), scale(0.40)`);
const downloads = svg
.append('text')
Expand Down
19 changes: 19 additions & 0 deletions src/services/theme.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { lightTheme, darkTheme } from '../themes';

export class ThemeService {
static getStyleContent(theme: string | null): string {
let styleContent: string;
switch (theme) {
case 'light':
styleContent = lightTheme;
break;
case 'dark':
styleContent = darkTheme;
break;
default:
console.error(`Styles not found for theme '${theme}'.`);
return lightTheme;
}
return styleContent;
}
}
58 changes: 58 additions & 0 deletions src/themes/dark.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
export const darkTheme = `
#rect {
rx: 7;
fill: #222222;
stroke: rgb(228, 226, 226);
stroke-width: 1;
}
#name {
font-family: "Ubuntu", "Helvetica", sans-serif;
font-size: 20px;
font-style: italic;
fill: #f2f2f2;
}
#packagist-link {
font-family: "Ubuntu", "Helvetica", sans-serif;
font-size: 13px;
font-style: italic;
font-weight: 500;
fill: #f2f2f2;
}
.bundle-card {
fill: #444444;
stroke: #00CC00;
stroke-opacity: 0.35;
}
.bundle-name {
font-family: "Ubuntu", "Helvetica", sans-serif;
font-size: 13px;
font-weight: 600;
fill: #00CC00;
}
.bundle-description {
font-family: "Ubuntu", "Helvetica", sans-serif;
font-size: 11px;
fill: #f2f2f2;
}
.bundle-language {
font-family: "Ubuntu", "Helvetica", sans-serif;
font-size: 12px;
fill: #f2f2f2;
}
.bundle-downloads {
font-family: "Ubuntu", "Helvetica", sans-serif;
font-size: 12px;
fill: #f2f2f2;
}
.bundle-stars {
font-family: "Ubuntu", "Helvetica", sans-serif;
font-size: 12px;
fill: #f2f2f2;
}
.download-icon {
fill: #f2f2f2;
}
.star-icon {
fill: #f2f2f2;
}
`;
2 changes: 2 additions & 0 deletions src/themes/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './light';
export * from './dark';
7 changes: 2 additions & 5 deletions src/styles/card.ts → src/themes/light.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
export const cardCss = `
#circle-border {
fill: gray;
}
export const lightTheme = `
#rect {
rx: 7;
fill: #FAFAFA;
stroke: rgb(228, 226, 226);;
stroke: rgb(228, 226, 226);
stroke-width: 1;
}
#name {
Expand Down
Loading