Skip to content

Commit

Permalink
#86 - add progress bar in order to track requests limit
Browse files Browse the repository at this point in the history
  • Loading branch information
kas-elvirov committed Jan 8, 2025
1 parent f0b54fe commit b35abd3
Show file tree
Hide file tree
Showing 15 changed files with 236 additions and 13 deletions.
4 changes: 3 additions & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
VITE_APP_APP_VERSION=10.0.12
VITE_APP_APP_VERSION=10.0.14
VITE_APP_GITHUB_API_FREE_HOURLY_LIMIT=60
VITE_APP_GITHUB_API_TOKENIZED_HOURLY_LIMIT=5000
VITE_APP_TOKEN_CREATION_LINK=https://github.com/settings/tokens/new?scopes=repo&description=Github%20GLOC
VITE_APP_APPLICATION_REPO=https://github.com/kas-elvirov/gloc
VITE_APP_DEVELOPER_WEBSITE=https://kas-elvirov.com
Expand Down
4 changes: 3 additions & 1 deletion .env.development
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
VITE_APP_APP_VERSION=10.0.12
VITE_APP_APP_VERSION=10.0.14
VITE_APP_GITHUB_API_FREE_HOURLY_LIMIT=60
VITE_APP_GITHUB_API_TOKENIZED_HOURLY_LIMIT=5000
VITE_APP_TOKEN_CREATION_LINK=https://github.com/settings/tokens/new?scopes=repo&description=Github%20GLOC
VITE_APP_APPLICATION_REPO=https://github.com/kas-elvirov/gloc
VITE_APP_DEVELOPER_WEBSITE=https://kas-elvirov.com
Expand Down
4 changes: 3 additions & 1 deletion .env.production
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
VITE_APP_APP_VERSION=10.0.12
VITE_APP_APP_VERSION=10.0.14
VITE_APP_GITHUB_API_FREE_HOURLY_LIMIT=60
VITE_APP_GITHUB_API_TOKENIZED_HOURLY_LIMIT=5000
VITE_APP_TOKEN_CREATION_LINK=https://github.com/settings/tokens/new?scopes=repo&description=Github%20GLOC
VITE_APP_APPLICATION_REPO=https://github.com/kas-elvirov/gloc
VITE_APP_DEVELOPER_WEBSITE=https://kas-elvirov.com
Expand Down
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"short_name": "Gloc",
"author": "Kas Elvirov",
"description": "Github Gloc - counts locs on GitHub pages",
"version": "10.0.12",
"version": "10.0.14",
"action": {
"default_icon": {
"16": "img/icon16.png",
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "gloc",
"version": "10.0.12",
"version": "10.0.14",
"engines": {
"node": "16.19.0",
"npm": "0.39.3"
Expand Down
6 changes: 6 additions & 0 deletions scripts/upAppVersion.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const manifest = require('../manifest.json');
const env = '.env';
let parsedEnv = envfile.parse(env);
parsedEnv.VITE_APP_APP_VERSION = package.version;
parsedEnv.VITE_APP_GITHUB_API_FREE_HOURLY_LIMIT = 60;
parsedEnv.VITE_APP_GITHUB_API_TOKENIZED_HOURLY_LIMIT = 5000;
parsedEnv.VITE_APP_TOKEN_CREATION_LINK = 'https://github.com/settings/tokens/new?scopes=repo&description=Github%20GLOC';
parsedEnv.VITE_APP_APPLICATION_REPO = 'https://github.com/kas-elvirov/gloc';
parsedEnv.VITE_APP_DEVELOPER_WEBSITE = 'https://kas-elvirov.com';
Expand All @@ -22,6 +24,8 @@ fs.writeFileSync('./.env', envfile.stringify(parsedEnv));
const envDevelopment = '.env.development';
let parsedEnvDevelopment = envfile.parse(envDevelopment);
parsedEnvDevelopment.VITE_APP_APP_VERSION = package.version;
parsedEnvDevelopment.VITE_APP_GITHUB_API_FREE_HOURLY_LIMIT = 60;
parsedEnvDevelopment.VITE_APP_GITHUB_API_TOKENIZED_HOURLY_LIMIT = 5000;
parsedEnvDevelopment.VITE_APP_TOKEN_CREATION_LINK =
'https://github.com/settings/tokens/new?scopes=repo&description=Github%20GLOC';
parsedEnvDevelopment.VITE_APP_APPLICATION_REPO = 'https://github.com/kas-elvirov/gloc';
Expand All @@ -35,6 +39,8 @@ fs.writeFileSync('./.env.development', envfile.stringify(parsedEnvDevelopment));
const envProduction = '.env.production';
let parsedEnvProduction = envfile.parse(envProduction);
parsedEnvProduction.VITE_APP_APP_VERSION = package.version;
parsedEnvProduction.VITE_APP_GITHUB_API_FREE_HOURLY_LIMIT = 60;
parsedEnvProduction.VITE_APP_GITHUB_API_TOKENIZED_HOURLY_LIMIT = 5000;
parsedEnvProduction.VITE_APP_TOKEN_CREATION_LINK =
'https://github.com/settings/tokens/new?scopes=repo&description=Github%20GLOC';
parsedEnvProduction.VITE_APP_APPLICATION_REPO = 'https://github.com/kas-elvirov/gloc';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { FC } from 'react';

import { Box, LinearProgress, Typography } from '@mui/material';

import { LinearProgressWithLabelProps } from './LinearProgressWithLabel.types';

export const LinearProgressWithLabel: FC<
LinearProgressWithLabelProps
> = props => {
return (
<Box sx={{ display: 'flex', alignItems: 'center' }}>
<Box sx={{ width: '100%', mr: 1 }}>
<LinearProgress
variant='determinate'
{...props}
color={props.value < 100 ? 'primary' : 'error'}
/>
</Box>
<Box sx={{ minWidth: 35 }}>
<Typography
variant='body2'
sx={{ color: 'text.secondary' }}
>{`${Math.round(props.value)}%`}</Typography>
</Box>
</Box>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { LinearProgressProps } from '@mui/material';

export type LinearProgressWithLabelProps = LinearProgressProps & {
value: number;
};
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,6 @@ const getErrorMessage = ({
let isError = false;
const castedError = error as ErrorType;

console.group('getErrorMessage');
console.log('data', data);
console.log('error', error);
console.log('isObjectValid(data)', isObjectValid(data));
console.groupEnd();

if (castedError?.status === 202 && !isObjectValid(data)) {
return {
errorMessage: 'Needs to retry',
Expand Down
62 changes: 62 additions & 0 deletions src/_modules/Popup/components/PopupPage/PopupPage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
/* eslint-disable max-len */
import { LinearProgressWithLabel } from 'src/_lib/components/LinearProgressWithLabel/LinearProgressWithLabel';
import { SYSTEM_DEFAULTS } from 'src/_shared/consts/defaults';
import {
TrackEventsService,
TrackEventsState,
} from 'src/_shared/services/TrackEvent/TrackEvent';

import React, { FC, useEffect } from 'react';

Expand Down Expand Up @@ -31,14 +37,50 @@ export const PopupPage: FC = () => {
SYSTEM_DEFAULTS.STORAGE.APP_MODE.DEFAULT_VALUE,
);

const [freeHourlyApiUsage, setFreeHourlyApiStatPercent] = React.useState(0);
const [tokenizedHourlyApiUsage, setTokenizedHourlyApiStatPercent] =
React.useState(0);

useEffect(() => {
chrome?.storage?.sync?.get(
{
[SYSTEM_DEFAULTS.STORAGE.APP_MODE.KEY]:
SYSTEM_DEFAULTS.STORAGE.APP_MODE.DEFAULT_VALUE,
[SYSTEM_DEFAULTS.STORAGE.EVENTS_STAT.KEY]:
SYSTEM_DEFAULTS.STORAGE.EVENTS_STAT.DEFAULT_VALUE,
},
result => {
setAppStatus(result[SYSTEM_DEFAULTS.STORAGE.APP_MODE.KEY]);

if (
(result[SYSTEM_DEFAULTS.STORAGE.EVENTS_STAT.KEY] as TrackEventsState)[
SYSTEM_DEFAULTS.STORAGE.EVENTS_STAT.REQUESTS_STAT
]
) {
setFreeHourlyApiStatPercent(
TrackEventsService.calculatePercentOfHourlyEventUsage({
state: result[
SYSTEM_DEFAULTS.STORAGE.EVENTS_STAT.KEY
] as TrackEventsState,
eventName: SYSTEM_DEFAULTS.STORAGE.EVENTS_STAT.REQUESTS_STAT,
limit: Number(
import.meta.env.VITE_APP_GITHUB_API_FREE_HOURLY_LIMIT,
),
}),
);

setTokenizedHourlyApiStatPercent(
TrackEventsService.calculatePercentOfHourlyEventUsage({
state: result[
SYSTEM_DEFAULTS.STORAGE.EVENTS_STAT.KEY
] as TrackEventsState,
eventName: SYSTEM_DEFAULTS.STORAGE.EVENTS_STAT.REQUESTS_STAT,
limit: Number(
import.meta.env.VITE_APP_GITHUB_API_TOKENIZED_HOURLY_LIMIT,
),
}),
);
}
},
);
}, []);
Expand Down Expand Up @@ -102,6 +144,26 @@ export const PopupPage: FC = () => {
title={`App is ${isAppEnabled ? 'enabled' : 'disabled'}`}
/>

<Stack style={{ width: '100%' }}>
<Typography variant='body2'>
Free requests (GitHub limit -{' '}
{Number(import.meta.env.VITE_APP_GITHUB_API_FREE_HOURLY_LIMIT)} per
hour)
</Typography>

<LinearProgressWithLabel value={freeHourlyApiUsage} />
</Stack>

<Stack style={{ width: '100%' }}>
<Typography variant='body2'>
Tokenised requests (GitHub limit -{' '}
{Number(import.meta.env.VITE_APP_GITHUB_API_TOKENIZED_HOURLY_LIMIT)}{' '}
per hour)
</Typography>

<LinearProgressWithLabel value={tokenizedHourlyApiUsage} />
</Stack>

<Chip
avatar={
<Avatar>
Expand Down
8 changes: 8 additions & 0 deletions src/_shared/api/github/endpoints.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { SYSTEM_DEFAULTS } from 'src/_shared/consts/defaults';
import { TrackEventsService } from 'src/_shared/services/TrackEvent/TrackEvent';

import {
BaseQueryFn,
FetchBaseQueryError,
Expand Down Expand Up @@ -76,6 +79,11 @@ export const githubApi = createApi({
Accept: 'application/vnd.github.v3+json',
},
}),
onQueryStarted: () => {
TrackEventsService.trackEvent(
SYSTEM_DEFAULTS.STORAGE.EVENTS_STAT.REQUESTS_STAT,
);
},
extraOptions: { maxRetries: 5 },
}),
getAllUserRepos: builder.query<
Expand Down
5 changes: 5 additions & 0 deletions src/_shared/consts/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ export const SYSTEM_DEFAULTS = {
KEY: 'x-github-token',
DEFAULT_VALUE: '',
},
EVENTS_STAT: {
REQUESTS_STAT: 'getRepoCodeFrequency',
KEY: 'x-events-stat',
DEFAULT_VALUE: {},
},
},
DEBOUNCE: {
300: 300,
Expand Down
106 changes: 106 additions & 0 deletions src/_shared/services/TrackEvent/TrackEvent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { SYSTEM_DEFAULTS } from '../../consts/defaults';

export type TrackEventsEventName = string;
/**
* YYYY-MM-DD format
*/
export type TrackEventsCurrentDate = string;

export type TrackEventsState = Record<
TrackEventsEventName,
{
hourly: [
number,
number,
number,
number,
number,

number,
number,
number,
number,
number,

number,
number,
number,
number,
number,

number,
number,
number,
number,
number,

number,
number,
number,
number,
];
daily: Record<TrackEventsCurrentDate, number>;
}
>;

class TrackEvents {
state: TrackEventsState = {};

trackEvent = (eventName: TrackEventsEventName) => {
chrome?.storage?.sync?.get(
{
[SYSTEM_DEFAULTS.STORAGE.EVENTS_STAT.KEY]:
SYSTEM_DEFAULTS.STORAGE.EVENTS_STAT.DEFAULT_VALUE,
},
result => {
const now = new Date();

const currentHour = now.getHours();
const currentDate = now.toISOString().split('T')[0];

const state = {
...result[SYSTEM_DEFAULTS.STORAGE.EVENTS_STAT.KEY],
} as TrackEventsState;

if (!state[eventName]) {
state[eventName] = {
// @ts-expect-error Everything is okay (array sizes are compatible. I think)
hourly: Array(25).fill(0),
daily: {},
};
}

state[eventName].hourly[currentHour]++;

if (!state[eventName].daily[currentDate]) {
state[eventName].daily[currentDate] = 0;
}

state[eventName].daily[currentDate]++;

chrome.storage?.sync?.set?.(
{ [SYSTEM_DEFAULTS.STORAGE.EVENTS_STAT.KEY]: state },
() => {},
);
},
);
};

calculatePercentOfHourlyEventUsage = ({
state,
eventName,
limit,
}: {
state: TrackEventsState;
eventName: TrackEventsEventName;
limit: number;
}): number => {
const now = new Date();

const currentHour = now.getHours();

return state[eventName].hourly[currentHour] / (limit / 100);
};
}

export const TrackEventsService = new TrackEvents();
4 changes: 4 additions & 0 deletions src/environment.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ declare global {
*/
VITE_APP_APP_VERSION: string;

VITE_APP_GITHUB_API_FREE_HOURLY_LIMIT: string;

VITE_APP_GITHUB_API_TOKENIZED_HOURLY_LIMIT: string;

/**
* # Base of chrome extension settings link
*/
Expand Down

0 comments on commit b35abd3

Please sign in to comment.