diff --git a/docs/widgets.md b/docs/widgets.md
index d65a0f52..c444c16e 100644
--- a/docs/widgets.md
+++ b/docs/widgets.md
@@ -11,6 +11,7 @@ Dashy has support for displaying dynamic content in the form of widgets. There a
- [Crypto Price History](#crypto-token-price-history)
- [RSS Feed](#rss-feed)
- [XKCD Comics](#xkcd-comics)
+ - [Code Stats](#code-stats)
- [TFL Status](#tfl-status)
- [Exchange Rates](#exchange-rates)
- [Stock Price History](#stock-price-history)
@@ -229,6 +230,34 @@ Have a laugh with the daily comic from [XKCD](https://xkcd.com/). A classic webc
---
+### Code Stats
+
+Display your coding summary. [Code::Stats](https://codestats.net/) is a free and open source app that aggregates statistics about your programming activity. Dashy supports both the public instance, as well as self-hosted versions.
+
+

+
+##### Options
+
+**Field** | **Type** | **Required** | **Description**
+--- | --- | --- | ---
+**`username`** | `string` | Required | Your CodeStats username
+**`hostname`** | `string` | _Optional_ | If your self-hosting CodeStats, then supply the host name. By default it will use the public hosted instance
+**`monthsToShow`** | `number` | _Optional_ | Specify the number of months to render in the historical data chart. Defaults to `6`
+**`hideMeta`** | `boolean` | _Optional_ | Optionally hide the meta section (username, level, all-time and recent XP)
+**`hideHistory`** | `boolean` | _Optional_ | Optionally hide the historical calendar heat map
+**`hideLanguages`** | `boolean` | _Optional_ | Optionally hide the programming languages pie chart
+**`hideMachines`** | `boolean` | _Optional_ | Optionally hide the machines percentage chart
+
+##### Example
+
+```yaml
+- type: code-stats
+ options:
+ username: alicia
+```
+
+---
+
### TFL Status
Shows real-time tube status of the London Underground. All options are optional.
diff --git a/src/components/Widgets/CodeStats.vue b/src/components/Widgets/CodeStats.vue
new file mode 100644
index 00000000..61c3ae69
--- /dev/null
+++ b/src/components/Widgets/CodeStats.vue
@@ -0,0 +1,244 @@
+
+
+
+
+
+
+
diff --git a/src/components/Widgets/WidgetBase.vue b/src/components/Widgets/WidgetBase.vue
index 1b7ac5d2..416a3220 100644
--- a/src/components/Widgets/WidgetBase.vue
+++ b/src/components/Widgets/WidgetBase.vue
@@ -39,6 +39,13 @@
@error="handleError"
:ref="widgetRef"
/>
+
{
if (currencies[code]) return currencies[code];
return code;
};
+
+/* Given a large number, will add commas to make more readable */
+export const putCommasInBigNum = (bigNum) => {
+ const strNum = Number.isNaN(bigNum) ? bigNum : String(bigNum);
+ return strNum.replace(/\B(?=(?:\d{3})+(?!\d))/g, ',');
+};
+
+/* Given a large number, will convert 1000 into k for readability */
+export const showNumAsThousand = (bigNum) => {
+ if (bigNum < 1000) return bigNum;
+ return `${Math.round(bigNum / 1000)}k`;
+};
diff --git a/src/utils/defaults.js b/src/utils/defaults.js
index 5373ab69..19da9cbd 100644
--- a/src/utils/defaults.js
+++ b/src/utils/defaults.js
@@ -217,6 +217,7 @@ module.exports = {
jokes: 'https://v2.jokeapi.dev/joke/',
flights: 'https://aerodatabox.p.rapidapi.com/flights/airports/icao/',
rssToJson: 'https://api.rss2json.com/v1/api.json',
+ codeStats: 'https://codestats.net/',
},
/* URLs for web search engines */
searchEngineUrls: {