Skip to content

Commit 70623e4

Browse files
added undefined, null and boolean support
colors moved to config.ts
1 parent 65d6710 commit 70623e4

File tree

7 files changed

+81
-96
lines changed

7 files changed

+81
-96
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ lerna-debug.log*
1919
# Tests
2020
/coverage
2121
/.nyc_output
22+
debug.json
2223

2324
# IDEs and editors
2425
/.idea

src/apis/apis.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export class APIService {
1717
'https://api.github.com/graphql',
1818
{
1919
query: "query GetUserDetails($username: String!) { user(login: $username)" +
20-
"{ name login followers { totalCount } repositories(first: 10, orderBy: {field: STARGAZERS, direction: DESC})" +
20+
"{ name login followers { totalCount } repositories(first: 3, orderBy: {field: STARGAZERS, direction: DESC})" +
2121
"{ nodes { name stargazerCount } totalCount } } } }",
2222
variables: {
2323
username: username

src/config.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
type typeofTypes = 'string' | 'boolean' | 'function' | 'number' | 'object' | 'symbol' | 'undefined' | 'bigint';
2+
3+
export const brackets_colors = ['#ffd700', '#da70d6', '#179fff'];
4+
5+
export const typeColors = (type: typeofTypes) => {
6+
switch (type) {
7+
case 'bigint': return '#b5cea8';
8+
case 'number': return '#b5cea8';
9+
case 'object': return '#569cd6';
10+
case 'undefined': return '#569cd6';
11+
case 'boolean': return '#569cd6';
12+
default: return '#ce9178';
13+
}
14+
}
15+
16+
export const typeQuotes = (type: typeofTypes) => {
17+
const quotesNeeded: typeofTypes[] = ['string', 'symbol'];
18+
return quotesNeeded.includes(type) ? '"' : '';
19+
}
20+
21+
export const colors = {
22+
main_text: '#ffffff',
23+
background: '#1e1e1e',
24+
header: '#252526',
25+
icon_color: '#ffd700',
26+
indent_lines: '#404040',
27+
line_index: '#6e7681',
28+
keys: '#9cdcfe'
29+
}

src/json_parser/parser.service.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Injectable } from '@nestjs/common';
2+
import { brackets_colors, colors, typeColors, typeQuotes } from 'src/config';
23

34
type AnyObject = Record<string, any>;
4-
const brackets_colors = ['#ffd700', '#da70d6', '#179fff'];
55

66
export type ObjectStructureInfo = {
77
key: string;
@@ -20,18 +20,20 @@ export class ParserService {
2020
const currentIndent = indent * depth;
2121
const nextIndent = indent * (depth + 1);
2222

23-
if (typeof obj !== "object" || obj === null) {
24-
const quotes = typeof obj === 'number' ? '' : '"';
25-
const color = typeof obj === 'number' ? '#b5cea8' : '#ce9178';
23+
if (typeof obj !== "object" || obj === null || obj === undefined) {
24+
const quotes = typeQuotes(typeof obj);
25+
const color = typeColors(typeof obj);
2626
return `<tspan style="fill: ${color};">${quotes}${obj}${quotes}</tspan>`;
2727
}
2828

2929
const entries = Object.entries(obj)
3030
.map(([key, value], index, array) => {
3131
const formattedValue = this.parse(value, indent, depth + 1);
32-
const comma = index < array.length - 1 ? "," : "";
32+
const comma = index < array.length - 1 ? ',' : '';
3333

34-
return `<tspan x="${nextIndent}" dy="19"><tspan class="key">"${key}"</tspan>: ${formattedValue}${comma}</tspan>`;
34+
return `<tspan x="${nextIndent}" dy="19">` +
35+
`<tspan style="fill: ${colors.keys};">"${key}"</tspan>: ${formattedValue}${comma}` +
36+
`</tspan>`;
3537
})
3638
.join(`\n`);
3739

@@ -56,8 +58,8 @@ export class ParserService {
5658
);
5759
}
5860

59-
analyzeObjectStructureFlat(
60-
obj: any,
61+
parseObjectStructure(
62+
obj: AnyObject,
6163
lineIndex: { current: number } = { current: 2 },
6264
depth: number = 0
6365
): ObjectStructureInfo[] {
@@ -73,7 +75,7 @@ export class ParserService {
7375

7476
if (typeof obj[key] === 'object' && obj[key] !== null) {
7577
result.push({ key, startLine, endLine: 0, depth });
76-
const children = this.analyzeObjectStructureFlat(obj[key], lineIndex, depth + 1);
78+
const children = this.parseObjectStructure(obj[key], lineIndex, depth + 1);
7779
result.push(...children);
7880
const endLine = lineIndex.current++;
7981
result.find(item => item.key === key && item.startLine === startLine)!.endLine = endLine;

src/widget/views/index.hbs

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
<svg xmlns="http://www.w3.org/2000/svg" width="800" height="{{ height }}" viewBox="0 0 800 {{ height }}">
22
<style>
3-
.key {
4-
fill: #9cdcfe;
5-
}
6-
73
text {
8-
fill: white;
94
font-weight: normal;
105
transform: translateX(5px);
116
}
@@ -15,25 +10,24 @@
1510
}
1611
1712
.indexes {
18-
fill: #6e7681;
1913
transform: translateX(10px);
2014
}
2115
2216
.main_text {
2317
transform: translateX(38px);
2418
}
2519
</style>
26-
<rect width="800" height="{{ height_ }}" style="fill: #1e1e1e;" />
27-
<rect width="693" height="40" x="107" style="fill: #252526;" />
28-
<rect width="1" height="{{ height_main_line }}" x="40" y="65" style="fill: #404040;" />
20+
<rect width="800" height="{{ height_ }}" style="fill: {{background_color}};" />
21+
<rect width="693" height="40" x="107" style="fill: {{header_color}};" />
22+
<rect width="1" height="{{ height_main_line }}" x="40" y="65" fill="{{indent_color}}" />
2923

30-
<text y="60" font-family="Consolas, monospace" class="indexes">
24+
<text y="60" font-family="Consolas, monospace" class="indexes" fill="{{main_color}}">
3125
{{{indexes}}}
3226
</text>
33-
<text y="25" class="filename" font-family="Segoe WPC, Segoe UI, sans-serif">
34-
<tspan style="fill: #ffd700;" font-family="Consolas, monospace">{}</tspan> info.json
27+
<text y="25" class="filename" font-family="Segoe WPC, Segoe UI, sans-serif" fill="{{main_color}}">
28+
<tspan fill="{{icon_color}}" font-family="Consolas, monospace">{}</tspan> info.json
3529
</text>
36-
<text y="60" font-family="Consolas, monospace" class="main_text">
30+
<text y="60" font-family="Consolas, monospace" class="main_text" fill="{{main_color}}">
3731
{{{json}}}
3832
</text>
3933

src/widget/widget.controller.ts

Lines changed: 18 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
import { Get, Controller, Render, Header, Res, Query } from '@nestjs/common';
22
import type { Response } from 'express';
33
import { WidgetService } from './widget.service';
4+
import { ParserService } from 'src/json_parser/parser.service';
5+
import { colors } from 'src/config';
46

57

68
@Controller()
79
export class WidgetController {
8-
constructor(private readonly widgetService: WidgetService) { }
10+
constructor(private readonly widgetService: WidgetService,
11+
private readonly parserService: ParserService
12+
) { }
913

1014
@Get('/')
1115
@Render('index')
@@ -14,65 +18,28 @@ export class WidgetController {
1418
async widget(
1519
@Res({ passthrough: true }) res: Response
1620
) {
17-
const content = await this.widgetService.generate();
21+
const json = await this.widgetService.generate();
22+
const content = this.parserService.parse(json, 30);
1823

19-
const lines_count = content.main.split('\n').length;
24+
const indents = this.parserService.parseObjectStructure(json);
25+
26+
const lines_count = content.split('\n').length;
2027
const indexes = this.widgetService.generate_indexes(lines_count);
2128

2229
res.header('Content-Type', 'image/svg+xml');
2330
return {
24-
json: content.main,
31+
json: content,
2532
indexes: indexes,
26-
indents: content.indents,
33+
indents: this.widgetService.generateIndentLines(indents, 30),
2734
height: 52 + (lines_count * 19),
2835
height_: 60 + (lines_count * 19),
29-
height_main_line: (lines_count - 2) * 19
30-
};
31-
}
32-
33-
/*
34-
@Get('/user')
35-
@Render('index')
36-
@Header('Cache-Control', 'no-cache')
37-
@Header('Age', '0')
38-
async widgetUser(
39-
@Res({ passthrough: true }) res: Response,
40-
@Query() query: { query: string }
41-
) {
42-
let json = {};
43-
let content = "";
44-
let indexes = ""
45-
let lines_count = 0;
36+
height_main_line: (lines_count - 2) * 19,
4637

47-
try {
48-
if (!query.query || query.query.length > 255) {
49-
throw Error('Invalid request query');
50-
}
51-
52-
json = JSON.parse(query.query);
53-
54-
content = await this.widgetService.generateUser(json);
55-
lines_count = content.split('\n').length;
56-
indexes = this.widgetService.generate_indexes(lines_count);
57-
} catch (e) {
58-
console.error(e)
59-
json = {
60-
status: 'error',
61-
message: (e.message ?? "Unknown error. See server console.").slice(0, 60) + (!!e.message && e.message.length > 60 ? '...' : '')
62-
}
63-
64-
content = await this.widgetService.generateUser(json);
65-
lines_count = content.split('\n').length;
66-
indexes = this.widgetService.generate_indexes(lines_count);
67-
}
68-
69-
res.header('Content-Type', 'image/svg+xml');
70-
return {
71-
json: content,
72-
indexes: indexes,
73-
height: 52 + (lines_count * 19),
74-
height_: 60 + (lines_count * 19)
38+
background_color: colors.background,
39+
header_color: colors.header,
40+
icon_color: colors.icon_color,
41+
indent_color: colors.indent_lines,
42+
main_color: colors.main_text
7543
};
7644
}
77-
*/
7845
}

src/widget/widget.service.ts

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { Injectable } from '@nestjs/common';
22
import { APIService } from 'src/apis/apis.service';
3-
import { ObjectStructureInfo, ParserService } from 'src/json_parser/parser.service';
3+
import { colors } from 'src/config';
4+
import { ObjectStructureInfo } from 'src/json_parser/parser.service';
45

56

67
@Injectable()
78
export class WidgetService {
8-
constructor(private readonly parserService: ParserService,
9+
constructor(
910
private readonly apiService: APIService,
1011
) { }
1112

@@ -66,7 +67,7 @@ export class WidgetService {
6667
return acc;
6768
}, {});
6869

69-
const top_langs = wakatime_last.data?.slice(0, 3)?.reduce((acc, value) => {
70+
const top_langs = wakatime_last?.data?.slice(0, 3)?.reduce((acc, value) => {
7071
const el = { [value.name.toLowerCase().replaceAll('+', 'p')]: value.text };
7172
acc = { ...acc, ...el };
7273
return acc;
@@ -75,21 +76,21 @@ export class WidgetService {
7576
json = {
7677
name: github_data.data.user?.name ?? 'n/a',
7778
description: process.env.DESCRIPTION,
78-
followers: github_data.data.user?.followers?.totalCount ?? 'n/a',
79-
total_stars: github_data.data.user?.repositories?.totalCount ?? 'n/a',
80-
top_repos: top_repos ?? 'n/a',
79+
followers: github_data.data.user?.followers?.totalCount,
80+
total_stars: github_data.data.user?.repositories?.totalCount,
81+
top_repos: top_repos,
8182
github_streak: streak ? {
8283
current_streak: streak.streak,
8384
longest_streak: streak.longest
84-
} : 'n/a',
85+
} : undefined,
8586
wakatime: {
86-
all_time: wakatime_global.data.grand_total.human_readable_total_including_other_language ?? 'n/a',
87-
top_langs: top_langs ?? 'n/a'
87+
all_time: wakatime_global?.data?.grand_total?.human_readable_total_including_other_language,
88+
top_langs: top_langs
8889
},
8990
weather: weather ? {
9091
temperature: weather.temp,
9192
condition: weather.condition
92-
} : 'n/a',
93+
} : undefined,
9394
datetime: {
9495
time: this.getTime(),
9596
tz: process.env.DATETIME_TIMEZONE,
@@ -109,22 +110,13 @@ export class WidgetService {
109110
message: (e.message ?? "Unknown error. See server console.").slice(0, 60) + (!!e.message && e.message.length > 60 ? '...' : '')
110111
}
111112
}
112-
113-
const indents = this.parserService.analyzeObjectStructureFlat(json);
114-
return {
115-
main: this.parserService.parse(json, 30),
116-
indents: this.generateIndentLines(indents, 30)
117-
};
118-
}
119-
120-
async generateUser(obj: any) {
121-
return this.parserService.parse(obj, 30);
113+
return json;
122114
}
123115

124116
generate_indexes(count: number) {
125117
const array = [];
126118
for (let index = 1; index <= count; index++) {
127-
array.push(`<tspan x="${index < 10 ? '9' : '0'}" dy="${index === 1 ? '0' : '19'}">${index}</tspan>`);
119+
array.push(`<tspan x="${index < 10 ? '9' : '0'}" dy="${index === 1 ? '0' : '19'}" fill="${colors.line_index}">${index}</tspan>`);
128120
}
129121

130122
return array.join('\n');
@@ -134,7 +126,7 @@ export class WidgetService {
134126
const array = [];
135127
for (const indent of indents) {
136128
array.push(
137-
`<rect fill="#404040" x="${indent.depth * indent_width}" ` +
129+
`<rect fill="${colors.indent_lines}" x="${indent.depth * indent_width}" ` +
138130
`y="${indent.startLine * 19}" width="1" height="${((indent.endLine - indent.startLine) - 1) * 19}" />`
139131
);
140132
}

0 commit comments

Comments
 (0)