mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-10-23 16:14:04 +00:00
Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
d2f5d3c3de | ||
|
130031c225 | ||
|
1c7257eeb0 | ||
|
214084262c | ||
|
92ce419f45 | ||
|
394d085846 | ||
|
ab53048d5f | ||
|
c3a302bc38 | ||
|
a16161cdb4 | ||
|
1dc113aaef | ||
|
e371e8fedf |
28
CHANGELOG.md
28
CHANGELOG.md
@@ -2,6 +2,34 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
## [2.6.0](https://github.com/CorentinTh/it-tools/compare/v2.5.3...v2.6.0) (2022-07-23)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **new-tool:** added chronometer ([130031c](https://github.com/CorentinTh/it-tools/commit/130031c2256f3d4d46948974b9de85ee6e92bf8b))
|
||||
* **search:** focus the search bar using Ctrl+K ([ab53048](https://github.com/CorentinTh/it-tools/commit/ab53048d5f6fdca7d00edbb79dee1a5409e6b11e))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **deps:** run dependencie audit auto fix ([a16161c](https://github.com/CorentinTh/it-tools/commit/a16161cdb48c064882b9dc91ec3d091d286f5c63))
|
||||
* **lint:** cleanned index.html ([c3a302b](https://github.com/CorentinTh/it-tools/commit/c3a302bc389a0e13aef4b14d5a9d3ec3a0d32729))
|
||||
* **text-statistics:** empty text mean 0 words and 0 lines ([92ce419](https://github.com/CorentinTh/it-tools/commit/92ce419f45e110509ab202485a36bf175ce345da))
|
||||
|
||||
|
||||
### Refactors
|
||||
|
||||
* added accessibility labels on icon buttons ([394d085](https://github.com/CorentinTh/it-tools/commit/394d085846d976219ea775c21cd7e77f0f72a12b))
|
||||
* **import:** auto reordered imports ([2140842](https://github.com/CorentinTh/it-tools/commit/214084262cec7fb881fd397626356b080ea1a5cc))
|
||||
|
||||
### [2.5.3](https://github.com/CorentinTh/it-tools/compare/v2.5.2...v2.5.3) (2022-07-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* updated license in README ([e371e8f](https://github.com/CorentinTh/it-tools/commit/e371e8fedfd68f3cf6ecd3fbc9e2da8849f7d5bd))
|
||||
|
||||
### [2.5.2](https://github.com/CorentinTh/it-tools/compare/v2.5.1...v2.5.2) (2022-07-21)
|
||||
|
||||
### [2.5.1](https://github.com/CorentinTh/it-tools/compare/v2.5.0...v2.5.1) (2022-06-01)
|
||||
|
@@ -76,4 +76,4 @@ This project is continuously deployed using [vercel.com](https://vercel.com).
|
||||
|
||||
## License
|
||||
|
||||
This project is under the [MIT license](LICENSE).
|
||||
This project is under the [GNU GPLv3](LICENSE).
|
||||
|
24
index.html
24
index.html
@@ -6,11 +6,17 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>IT Tools - Handy online tools for developers</title>
|
||||
<meta itemprop="name" content="IT Tools - Handy online tools for developers" />
|
||||
<meta name="description" content="Collection of handy online tools for developers, with great UX. IT Tools is a free and open-source collection of handy online tools for developers & people working in IT." />
|
||||
<meta itemprop="description" content="Collection of handy online tools for developers, with great UX. IT Tools is a free and open-source collection of handy online tools for developers & people working in IT." />
|
||||
<meta
|
||||
name="description"
|
||||
content="Collection of handy online tools for developers, with great UX. IT Tools is a free and open-source collection of handy online tools for developers & people working in IT."
|
||||
/>
|
||||
<meta
|
||||
itemprop="description"
|
||||
content="Collection of handy online tools for developers, with great UX. IT Tools is a free and open-source collection of handy online tools for developers & people working in IT."
|
||||
/>
|
||||
<link rel="author" href="/humans.txt" />
|
||||
<link rel=canonical href="https://it-tools.tech">
|
||||
|
||||
<link rel="canonical" href="https://it-tools.tech" />
|
||||
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
|
||||
@@ -21,14 +27,20 @@
|
||||
<meta property="og:url" content="https://it-tools.tech/" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content="IT Tools - Handy online tools for developers" />
|
||||
<meta property="og:description" content="Collection of handy online tools for developers, with great UX. IT Tools is a free and open-source collection of handy online tools for developers & people working in IT." />
|
||||
<meta
|
||||
property="og:description"
|
||||
content="Collection of handy online tools for developers, with great UX. IT Tools is a free and open-source collection of handy online tools for developers & people working in IT."
|
||||
/>
|
||||
<meta property="og:image" content="/banner.png" />
|
||||
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta property="twitter:domain" content="it-tools.tech" />
|
||||
<meta property="twitter:url" content="https://it-tools.tech/" />
|
||||
<meta name="twitter:title" content="IT Tools - Handy online tools for developers" />
|
||||
<meta name="twitter:description" content="Collection of handy online tools for developers, with great UX. IT Tools is a free and open-source collection of handy online tools for developers & people working in IT." />
|
||||
<meta
|
||||
name="twitter:description"
|
||||
content="Collection of handy online tools for developers, with great UX. IT Tools is a free and open-source collection of handy online tools for developers & people working in IT."
|
||||
/>
|
||||
<meta name="twitter:image" content="/banner.png" />
|
||||
</head>
|
||||
<body>
|
||||
|
108
package-lock.json
generated
108
package-lock.json
generated
@@ -1,12 +1,13 @@
|
||||
{
|
||||
"name": "it-tools",
|
||||
"version": "2.5.2",
|
||||
"version": "2.6.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "it-tools",
|
||||
"version": "2.5.2",
|
||||
"version": "2.6.0",
|
||||
"license": "GNU GPLv3",
|
||||
"dependencies": {
|
||||
"@it-tools/bip39": "^0.0.4",
|
||||
"@vicons/material": "^0.12.0",
|
||||
@@ -1862,6 +1863,20 @@
|
||||
"url": "https://github.com/sponsors/CorentinTh"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/gen-mapping": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
|
||||
"integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/set-array": "^1.0.1",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10",
|
||||
"@jridgewell/trace-mapping": "^0.3.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/resolve-uri": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz",
|
||||
@@ -1871,6 +1886,25 @@
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/set-array": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
|
||||
"integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/source-map": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz",
|
||||
"integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/gen-mapping": "^0.3.0",
|
||||
"@jridgewell/trace-mapping": "^0.3.9"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/sourcemap-codec": {
|
||||
"version": "1.4.11",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz",
|
||||
@@ -1878,9 +1912,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@jridgewell/trace-mapping": {
|
||||
"version": "0.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz",
|
||||
"integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==",
|
||||
"version": "0.3.14",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz",
|
||||
"integrity": "sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/resolve-uri": "^3.0.3",
|
||||
@@ -9973,14 +10007,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/terser": {
|
||||
"version": "5.12.1",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.12.1.tgz",
|
||||
"integrity": "sha512-NXbs+7nisos5E+yXwAD+y7zrcTkMqb0dEJxIGtSKPdCBzopf7ni4odPul2aechpV7EXNvOudYOX2bb5tln1jbQ==",
|
||||
"version": "5.14.2",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz",
|
||||
"integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/source-map": "^0.3.2",
|
||||
"acorn": "^8.5.0",
|
||||
"commander": "^2.20.0",
|
||||
"source-map": "~0.7.2",
|
||||
"source-map-support": "~0.5.20"
|
||||
},
|
||||
"bin": {
|
||||
@@ -9996,15 +10030,6 @@
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/terser/node_modules/source-map": {
|
||||
"version": "0.7.3",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
|
||||
"integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/test-exclude": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
|
||||
@@ -12675,12 +12700,39 @@
|
||||
"nanoid": "^3.3.2"
|
||||
}
|
||||
},
|
||||
"@jridgewell/gen-mapping": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
|
||||
"integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jridgewell/set-array": "^1.0.1",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10",
|
||||
"@jridgewell/trace-mapping": "^0.3.9"
|
||||
}
|
||||
},
|
||||
"@jridgewell/resolve-uri": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz",
|
||||
"integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==",
|
||||
"dev": true
|
||||
},
|
||||
"@jridgewell/set-array": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
|
||||
"integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
|
||||
"dev": true
|
||||
},
|
||||
"@jridgewell/source-map": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz",
|
||||
"integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jridgewell/gen-mapping": "^0.3.0",
|
||||
"@jridgewell/trace-mapping": "^0.3.9"
|
||||
}
|
||||
},
|
||||
"@jridgewell/sourcemap-codec": {
|
||||
"version": "1.4.11",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz",
|
||||
@@ -12688,9 +12740,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@jridgewell/trace-mapping": {
|
||||
"version": "0.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz",
|
||||
"integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==",
|
||||
"version": "0.3.14",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz",
|
||||
"integrity": "sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jridgewell/resolve-uri": "^3.0.3",
|
||||
@@ -18758,14 +18810,14 @@
|
||||
}
|
||||
},
|
||||
"terser": {
|
||||
"version": "5.12.1",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.12.1.tgz",
|
||||
"integrity": "sha512-NXbs+7nisos5E+yXwAD+y7zrcTkMqb0dEJxIGtSKPdCBzopf7ni4odPul2aechpV7EXNvOudYOX2bb5tln1jbQ==",
|
||||
"version": "5.14.2",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz",
|
||||
"integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jridgewell/source-map": "^0.3.2",
|
||||
"acorn": "^8.5.0",
|
||||
"commander": "^2.20.0",
|
||||
"source-map": "~0.7.2",
|
||||
"source-map-support": "~0.5.20"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -18774,12 +18826,6 @@
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
||||
"dev": true
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.7.3",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
|
||||
"integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "it-tools",
|
||||
"version": "2.5.2",
|
||||
"version": "2.6.0",
|
||||
"description": "Collection of handy online tools for developers, with great UX. ",
|
||||
"keywords": [
|
||||
"productivity",
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { join, dirname } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { mkdir, readFile, writeFile } from 'fs/promises';
|
||||
import { dirname, join } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const currentDirname = dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
@@ -55,7 +55,7 @@ export const tool = defineTool({
|
||||
keywords: ['${toolName.split('-').join("', '")}'],
|
||||
component: () => import('./${toolName}.vue'),
|
||||
icon: ArrowsShuffle,
|
||||
};
|
||||
});
|
||||
`,
|
||||
);
|
||||
|
||||
|
@@ -9,6 +9,7 @@
|
||||
href="https://github.com/CorentinTh/it-tools"
|
||||
rel="noopener"
|
||||
target="_blank"
|
||||
aria-label="IT-Tools' github repository"
|
||||
>
|
||||
<n-icon size="25" :component="BrandGithub" />
|
||||
</n-button>
|
||||
@@ -26,17 +27,18 @@
|
||||
href="https://twitter.com/ittoolsdottech"
|
||||
rel="noopener"
|
||||
target="_blank"
|
||||
aria-label="IT Tools' twitter account"
|
||||
>
|
||||
<n-icon size="25" :component="BrandTwitter" />
|
||||
</n-button>
|
||||
</template>
|
||||
Creator twitter
|
||||
IT Tools' twitter account
|
||||
</n-tooltip>
|
||||
|
||||
<router-link to="/about" #="{ navigate, href }" custom>
|
||||
<n-tooltip trigger="hover">
|
||||
<template #trigger>
|
||||
<n-button tag="a" :href="href" circle quaternary size="large" aria-label="Home" @click="navigate">
|
||||
<n-button tag="a" :href="href" circle quaternary size="large" aria-label="About" @click="navigate">
|
||||
<n-icon size="25" :component="InfoCircle" />
|
||||
</n-button>
|
||||
</template>
|
||||
@@ -45,7 +47,7 @@
|
||||
</router-link>
|
||||
<n-tooltip trigger="hover">
|
||||
<template #trigger>
|
||||
<n-button size="large" circle quaternary @click="isDarkTheme = !isDarkTheme">
|
||||
<n-button size="large" circle quaternary aria-label="Toggle dark/light mode" @click="isDarkTheme = !isDarkTheme">
|
||||
<n-icon v-if="isDarkTheme" size="25" :component="Sun" />
|
||||
<n-icon v-else size="25" :component="Moon" />
|
||||
</n-button>
|
||||
@@ -57,8 +59,8 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useStyleStore } from '@/stores/style.store';
|
||||
import { BrandGithub, BrandTwitter, InfoCircle, Moon, Sun } from '@vicons/tabler';
|
||||
import { toRefs } from 'vue';
|
||||
import { BrandGithub, BrandTwitter, Moon, Sun, InfoCircle } from '@vicons/tabler';
|
||||
|
||||
const styleStore = useStyleStore();
|
||||
const { isDarkTheme } = toRefs(styleStore);
|
||||
|
@@ -1,8 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import { SearchRound } from '@vicons/material';
|
||||
import { computed, ref } from 'vue';
|
||||
import { deburr } from 'lodash';
|
||||
import { tools } from '@/tools';
|
||||
import { SearchRound } from '@vicons/material';
|
||||
import { useMagicKeys, whenever } from '@vueuse/core';
|
||||
import { deburr } from 'lodash';
|
||||
import { computed, ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
const router = useRouter();
|
||||
@@ -28,6 +29,21 @@ function onSelect(path: string) {
|
||||
router.push(path);
|
||||
queryString.value = '';
|
||||
}
|
||||
|
||||
const focusTarget = ref();
|
||||
|
||||
const keys = useMagicKeys({
|
||||
passive: false,
|
||||
onEventFired(e) {
|
||||
if (e.ctrlKey && e.key === 'k' && e.type === 'keydown') {
|
||||
e.preventDefault();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
whenever(keys.ctrl_k, () => {
|
||||
focusTarget.value.focus();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -40,9 +56,10 @@ function onSelect(path: string) {
|
||||
>
|
||||
<template #default="{ handleInput, handleBlur, handleFocus, value: slotValue }">
|
||||
<n-input
|
||||
ref="focusTarget"
|
||||
round
|
||||
clearable
|
||||
placeholder="Search a tool..."
|
||||
placeholder="Search a tool... [Ctrl + K]"
|
||||
:value="slotValue"
|
||||
@input="handleInput"
|
||||
@focus="handleFocus"
|
||||
|
12
src/tools/chronometer/chronometer.service.test.ts
Normal file
12
src/tools/chronometer/chronometer.service.test.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { formatChronometerTime } from './chronometer.service';
|
||||
|
||||
describe('chronometer', () => {
|
||||
describe('formatChronometerTime', () => {
|
||||
it('format the elapsed time', () => {
|
||||
expect(formatChronometerTime({ elapsed: 123456 })).toEqual('02:03.456');
|
||||
expect(formatChronometerTime({ elapsed: 123456, msPerUnit: 100 })).toEqual('03:25:45.600');
|
||||
expect(formatChronometerTime({ elapsed: 12345600 })).toEqual('03:25:45.600');
|
||||
});
|
||||
});
|
||||
});
|
13
src/tools/chronometer/chronometer.service.ts
Normal file
13
src/tools/chronometer/chronometer.service.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
export function formatChronometerTime({ elapsed, msPerUnit = 1 }: { elapsed: number; msPerUnit?: number }) {
|
||||
const elapsedMs = elapsed * msPerUnit;
|
||||
|
||||
const ms = elapsedMs % 1000;
|
||||
const secs = ((elapsedMs - ms) / 1000) % 60;
|
||||
const mins = (((elapsedMs - ms) / 1000 - secs) / 60) % 60;
|
||||
const hrs = (((elapsedMs - ms) / 1000 - secs) / 60 - mins) / 60;
|
||||
const hrsString = hrs > 0 ? `${hrs.toString().padStart(2, '0')}:` : '';
|
||||
|
||||
return `${hrsString}${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}.${ms
|
||||
.toString()
|
||||
.padStart(3, '0')}`;
|
||||
}
|
32
src/tools/chronometer/chronometer.vue
Normal file
32
src/tools/chronometer/chronometer.vue
Normal file
@@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<div>
|
||||
<n-card>
|
||||
<div class="duration">{{ formatChronometerTime({ elapsed: counter, msPerUnit }) }}</div>
|
||||
</n-card>
|
||||
<br />
|
||||
<n-space justify="center">
|
||||
<n-button v-if="!isActive" secondary type="primary" @click="resume">Start</n-button>
|
||||
<n-button v-else secondary type="warning" @click="pause">Stop</n-button>
|
||||
|
||||
<n-button secondary @click="counter = 0">Reset</n-button>
|
||||
</n-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useInterval } from '@vueuse/core';
|
||||
import { formatChronometerTime } from './chronometer.service';
|
||||
|
||||
const msPerUnit = 10;
|
||||
|
||||
const { counter, pause, resume, isActive } = useInterval(msPerUnit, { controls: true, immediate: false });
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.duration {
|
||||
text-align: center;
|
||||
font-size: 40px;
|
||||
font-family: monospace;
|
||||
margin: 20px 0;
|
||||
}
|
||||
</style>
|
11
src/tools/chronometer/index.ts
Normal file
11
src/tools/chronometer/index.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { TimerOutlined } from '@vicons/material';
|
||||
import { defineTool } from '../tool';
|
||||
|
||||
export const tool = defineTool({
|
||||
name: 'Chronometer',
|
||||
path: '/chronometer',
|
||||
description: 'Monitor the duration of a thing. Basically a chronometer with simple chronometer features.',
|
||||
keywords: ['chronometer', 'time', 'lap', 'duration', 'measure', 'pause', 'resume', 'stopwatch'],
|
||||
component: () => import('./chronometer.vue'),
|
||||
icon: TimerOutlined,
|
||||
});
|
@@ -1,30 +1,31 @@
|
||||
import { LockOpen } from '@vicons/tabler';
|
||||
import type { ToolCategory } from './tool';
|
||||
|
||||
import { tool as mathEvaluator } from './math-evaluator';
|
||||
import { tool as jsonViewer } from './json-viewer';
|
||||
import { tool as htmlEntities } from './html-entities';
|
||||
import { tool as urlParser } from './url-parser';
|
||||
import { tool as deviceInformation } from './device-information';
|
||||
import { tool as bcrypt } from './bcrypt';
|
||||
import { tool as caseConverter } from './case-converter';
|
||||
import { tool as colorConverter } from './color-converter';
|
||||
import { tool as qrCodeGenerator } from './qr-code-generator';
|
||||
import { tool as base64Converter } from './base64-converter';
|
||||
import { tool as bcrypt } from './bcrypt';
|
||||
import { tool as bip39 } from './bip39-generator';
|
||||
import { tool as caseConverter } from './case-converter';
|
||||
import { tool as chronometer } from './chronometer';
|
||||
import { tool as colorConverter } from './color-converter';
|
||||
import { tool as crontabGenerator } from './crontab-generator';
|
||||
import { tool as dateTimeConverter } from './date-time-converter';
|
||||
import { tool as deviceInformation } from './device-information';
|
||||
import { tool as cypher } from './encryption';
|
||||
import { tool as gitMemo } from './git-memo';
|
||||
import { tool as hashText } from './hash-text';
|
||||
import { tool as htmlEntities } from './html-entities';
|
||||
import { tool as baseConverter } from './integer-base-converter';
|
||||
import { tool as jsonViewer } from './json-viewer';
|
||||
import { tool as loremIpsumGenerator } from './lorem-ipsum-generator';
|
||||
import { tool as mathEvaluator } from './math-evaluator';
|
||||
import { tool as qrCodeGenerator } from './qr-code-generator';
|
||||
import { tool as randomPortGenerator } from './random-port-generator';
|
||||
import { tool as romanNumeralConverter } from './roman-numeral-converter';
|
||||
import { tool as textStatistics } from './text-statistics';
|
||||
import { tool as tokenGenerator } from './token-generator';
|
||||
import { tool as hashText } from './hash-text';
|
||||
import { tool as uuidGenerator } from './uuid-generator';
|
||||
import { tool as romanNumeralConverter } from './roman-numeral-converter';
|
||||
import { tool as cypher } from './encryption';
|
||||
import { tool as bip39 } from './bip39-generator';
|
||||
import { tool as dateTimeConverter } from './date-time-converter';
|
||||
import { tool as gitMemo } from './git-memo';
|
||||
import { tool as baseConverter } from './integer-base-converter';
|
||||
import { tool as urlEncoder } from './url-encoder';
|
||||
import { tool as randomPortGenerator } from './random-port-generator';
|
||||
import { tool as loremIpsumGenerator } from './lorem-ipsum-generator';
|
||||
import { tool as urlParser } from './url-parser';
|
||||
import { tool as uuidGenerator } from './uuid-generator';
|
||||
|
||||
export const toolsByCategory: ToolCategory[] = [
|
||||
{
|
||||
@@ -59,6 +60,11 @@ export const toolsByCategory: ToolCategory[] = [
|
||||
icon: LockOpen,
|
||||
components: [mathEvaluator],
|
||||
},
|
||||
{
|
||||
name: 'Measurement',
|
||||
icon: LockOpen,
|
||||
components: [chronometer],
|
||||
},
|
||||
{
|
||||
name: 'Text',
|
||||
icon: LockOpen,
|
||||
|
@@ -5,19 +5,17 @@
|
||||
<br />
|
||||
<n-space justify="space-around">
|
||||
<n-statistic label="Character count" :value="text.length" />
|
||||
<n-statistic label="Word count" :value="text.split(/\s+/).length" />
|
||||
<n-statistic label="Line count" :value="text.split(/\r\n|\r|\n/).length" />
|
||||
<n-statistic label="Word count" :value="text === '' ? 0 : text.split(/\s+/).length" />
|
||||
<n-statistic label="Line count" :value="text === '' ? 0 : text.split(/\r\n|\r|\n/).length" />
|
||||
<n-statistic label="Byte size" :value="formatBytes(getStringSizeInBytes(text))" />
|
||||
</n-space>
|
||||
</n-card>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { formatBytes } from '@/utils/convert';
|
||||
import { ref } from 'vue';
|
||||
import { getStringSizeInBytes } from './text-statistics.service';
|
||||
|
||||
const text = ref(
|
||||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Commodo risus faucibus varius volutpat habitasse suspendisse justo inceptos primis mi. Fusce molestie lorem bibendum habitasse litora adipiscing turpis egestas quis nec. Non id conubia vulputate etiam iaculis vitae venenatis hac fusce condimentum. Adipiscing pellentesque venenatis ornare pulvinar tempus hac montes velit erat convallis.',
|
||||
);
|
||||
const text = ref('');
|
||||
</script>
|
||||
|
Reference in New Issue
Block a user