From 374caa176e6fe3bea4a223f191bd65b5af8f987d Mon Sep 17 00:00:00 2001 From: sharevb Date: Sat, 18 May 2024 15:08:27 +0200 Subject: [PATCH 1/4] fix(Phone Parser): store country prefix FIx #1040 --- src/composable/queryParams.ts | 31 ++++++++++++++++++- .../phone-parser-and-formatter.vue | 3 +- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/composable/queryParams.ts b/src/composable/queryParams.ts index 9699abbc..9e184610 100644 --- a/src/composable/queryParams.ts +++ b/src/composable/queryParams.ts @@ -1,7 +1,8 @@ import { useRouteQuery } from '@vueuse/router'; import { computed } from 'vue'; +import { useStorage } from '@vueuse/core'; -export { useQueryParam }; +export { useQueryParam, useQueryParamOrStorage }; const transformers = { number: { @@ -33,3 +34,31 @@ function useQueryParam({ name, defaultValue }: { name: string; defaultValue: }, }); } + +function useQueryParamOrStorage({ name, storageName, defaultValue }: { name: string; storageName: string; defaultValue?: T }) { + const type = typeof defaultValue; + const transformer = transformers[type as keyof typeof transformers] ?? transformers.string; + + const storageRef = useStorage(storageName, defaultValue); + const storageDefaultValue = storageRef.value ?? defaultValue; + + const proxy = useRouteQuery(name, transformer.toQuery(storageDefaultValue as never)); + + const ref = computed({ + get() { + return transformer.fromQuery(proxy.value) as unknown as T; + }, + set(value) { + proxy.value = transformer.toQuery(value as never); + }, + }); + + watch( + ref, + (newValue) => { + storageRef.value = newValue; + }, + ); + + return ref; +} diff --git a/src/tools/phone-parser-and-formatter/phone-parser-and-formatter.vue b/src/tools/phone-parser-and-formatter/phone-parser-and-formatter.vue index 5bc67780..1d721449 100644 --- a/src/tools/phone-parser-and-formatter/phone-parser-and-formatter.vue +++ b/src/tools/phone-parser-and-formatter/phone-parser-and-formatter.vue @@ -9,9 +9,10 @@ import { import { withDefaultOnError } from '@/utils/defaults'; import { booleanToHumanReadable } from '@/utils/boolean'; import { useValidation } from '@/composable/validation'; +import { useQueryParamOrStorage } from '@/composable/queryParams'; const rawPhone = ref(''); -const defaultCountryCode = ref(getDefaultCountryCode()); +const defaultCountryCode = useQueryParamOrStorage({ name: 'country', storageName: 'phone-parser:country', defaultValue: getDefaultCountryCode() }); const validation = useValidation({ source: rawPhone, rules: [ From c6b75ca3baae08157c8bf4a5c86706ffb346c8ac Mon Sep 17 00:00:00 2001 From: ShareVB Date: Sun, 14 Jul 2024 23:30:34 +0200 Subject: [PATCH 2/4] fix: update queryParams --- src/composable/queryParams.ts | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/composable/queryParams.ts b/src/composable/queryParams.ts index 9e184610..7cc8cc0d 100644 --- a/src/composable/queryParams.ts +++ b/src/composable/queryParams.ts @@ -17,6 +17,12 @@ const transformers = { fromQuery: (value: string) => value.toLowerCase() === 'true', toQuery: (value: boolean) => (value ? 'true' : 'false'), }, + object: { + fromQuery: (value: string) => { + return JSON.parse(value); + }, + toQuery: (value: object) => JSON.stringify(value), + }, }; function useQueryParam({ name, defaultValue }: { name: string; defaultValue: T }) { @@ -35,30 +41,26 @@ function useQueryParam({ name, defaultValue }: { name: string; defaultValue: }); } -function useQueryParamOrStorage({ name, storageName, defaultValue }: { name: string; storageName: string; defaultValue?: T }) { +function useQueryParamOrStorage({ name, storageName, defaultValue }: { name: string; storageName: string; defaultValue: T }) { const type = typeof defaultValue; const transformer = transformers[type as keyof typeof transformers] ?? transformers.string; const storageRef = useStorage(storageName, defaultValue); - const storageDefaultValue = storageRef.value ?? defaultValue; + const proxyDefaultValue = transformer.toQuery(defaultValue as never); + const proxy = useRouteQuery(name, proxyDefaultValue); - const proxy = useRouteQuery(name, transformer.toQuery(storageDefaultValue as never)); + const r = ref(defaultValue); - const ref = computed({ - get() { - return transformer.fromQuery(proxy.value) as unknown as T; - }, - set(value) { + watch(r, + (value) => { proxy.value = transformer.toQuery(value as never); + storageRef.value = value as never; }, - }); + { deep: true }); - watch( - ref, - (newValue) => { - storageRef.value = newValue; - }, - ); + r.value = (proxy.value && proxy.value !== proxyDefaultValue + ? transformer.fromQuery(proxy.value) as unknown as T + : storageRef.value as T) as never; - return ref; + return r; } From ba2d10af9d90202cc8fed7d2428e75fb06b99583 Mon Sep 17 00:00:00 2001 From: ShareVB Date: Sun, 22 Sep 2024 19:45:05 +0200 Subject: [PATCH 3/4] feat: add whatsapp/sms message links forger Fix #635 --- components.d.ts | 3 + src/tools/phone-parser-and-formatter/index.ts | 9 ++- .../phone-parser-and-formatter.vue | 57 ++++++++++++++++++- 3 files changed, 64 insertions(+), 5 deletions(-) diff --git a/components.d.ts b/components.d.ts index f2c3146f..bbc04bc9 100644 --- a/components.d.ts +++ b/components.d.ts @@ -126,7 +126,9 @@ declare module '@vue/runtime-core' { MenuLayout: typeof import('./src/components/MenuLayout.vue')['default'] MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default'] MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default'] + NA: typeof import('naive-ui')['NA'] NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default'] + NButton: typeof import('naive-ui')['NButton'] NCode: typeof import('naive-ui')['NCode'] NCollapseTransition: typeof import('naive-ui')['NCollapseTransition'] NConfigProvider: typeof import('naive-ui')['NConfigProvider'] @@ -145,6 +147,7 @@ declare module '@vue/runtime-core' { NMenu: typeof import('naive-ui')['NMenu'] NScrollbar: typeof import('naive-ui')['NScrollbar'] NSpin: typeof import('naive-ui')['NSpin'] + NTable: typeof import('naive-ui')['NTable'] NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default'] OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default'] PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default'] diff --git a/src/tools/phone-parser-and-formatter/index.ts b/src/tools/phone-parser-and-formatter/index.ts index 094b21e8..d3f28867 100644 --- a/src/tools/phone-parser-and-formatter/index.ts +++ b/src/tools/phone-parser-and-formatter/index.ts @@ -1,11 +1,11 @@ import { Phone } from '@vicons/tabler'; import { defineTool } from '../tool'; -import { translate } from '@/plugins/i18n.plugin'; export const tool = defineTool({ - name: translate('tools.phone-parser-and-formatter.title'), + name: 'Phone parser and formatter', path: '/phone-parser-and-formatter', - description: translate('tools.phone-parser-and-formatter.description'), + description: + 'Parse, validate and format phone numbers. Get information about the phone number, like the country code, type, etc. Forge link to send message in WhatsApp and SMS', keywords: [ 'phone', 'parser', @@ -18,6 +18,9 @@ export const tool = defineTool({ 'cell', 'international', 'national', + 'whatsapp', + 'sms', + 'message', ], component: () => import('./phone-parser-and-formatter.vue'), icon: Phone, diff --git a/src/tools/phone-parser-and-formatter/phone-parser-and-formatter.vue b/src/tools/phone-parser-and-formatter/phone-parser-and-formatter.vue index 1d721449..f4b83e06 100644 --- a/src/tools/phone-parser-and-formatter/phone-parser-and-formatter.vue +++ b/src/tools/phone-parser-and-formatter/phone-parser-and-formatter.vue @@ -23,13 +23,16 @@ const validation = useValidation({ ], }); -const parsedDetails = computed(() => { +const parsedRaw = computed(() => { if (!validation.isValid) { return undefined; } - const parsed = withDefaultOnError(() => parsePhoneNumber(rawPhone.value, defaultCountryCode.value), undefined); + return withDefaultOnError(() => parsePhoneNumber(rawPhone.value, defaultCountryCode.value), undefined); +}); +const parsedDetails = computed(() => { + const parsed = parsedRaw.value; if (!parsed) { return undefined; } @@ -82,6 +85,27 @@ const countriesOptions = getCountries().map(code => ({ label: `${lookup.byIso(code)?.country || code} (+${getCountryCallingCode(code)})`, value: code, })); + +const messageToSend = ref(''); +const whatsAppLink = computed(() => { + const parsed = parsedRaw.value; + if (!parsed) { + return undefined; + } + + const internationalNoPunts = parsed.formatInternational().replace(/^\+0*/g, '').replace(/\D/g, ''); + + return `https://wa.me/${internationalNoPunts}?text=${encodeURIComponent(messageToSend.value)}`; +}); +const smsLink = computed(() => { + const parsed = parsedRaw.value; + if (!parsed) { + return undefined; + } + + const internationalNoSpaces = parsed.formatInternational().replace(/\s/g, ''); + return `sms:${internationalNoSpaces}&body=${encodeURIComponent(messageToSend.value)}`; +}); From c6adf164af64b97191429f9df5ab99897a7482d7 Mon Sep 17 00:00:00 2001 From: ShareVB Date: Sat, 28 Sep 2024 10:41:59 +0200 Subject: [PATCH 4/4] fix: translate --- locales/en.yml | 2 +- src/tools/phone-parser-and-formatter/index.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/locales/en.yml b/locales/en.yml index d09d435a..b9abd177 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -298,7 +298,7 @@ tools: phone-parser-and-formatter: title: Phone parser and formatter - description: Parse, validate and format phone numbers. Get information about the phone number, like the country code, type, etc. + description: Parse, validate and format phone numbers. Get information about the phone number, like the country code, type, etc. Forge link to send message in WhatsApp and SMS. ipv4-subnet-calculator: title: IPv4 subnet calculator diff --git a/src/tools/phone-parser-and-formatter/index.ts b/src/tools/phone-parser-and-formatter/index.ts index d3f28867..24ea425e 100644 --- a/src/tools/phone-parser-and-formatter/index.ts +++ b/src/tools/phone-parser-and-formatter/index.ts @@ -1,11 +1,11 @@ import { Phone } from '@vicons/tabler'; import { defineTool } from '../tool'; +import { translate } from '@/plugins/i18n.plugin'; export const tool = defineTool({ - name: 'Phone parser and formatter', + name: translate('tools.phone-parser-and-formatter.title'), path: '/phone-parser-and-formatter', - description: - 'Parse, validate and format phone numbers. Get information about the phone number, like the country code, type, etc. Forge link to send message in WhatsApp and SMS', + description: translate('tools.phone-parser-and-formatter.description'), keywords: [ 'phone', 'parser',