diff --git a/public/bg.svg b/public/bg.svg deleted file mode 100644 index 5f756111bcb575f0931f1d96cebdbb55a74480b8..0000000000000000000000000000000000000000 --- a/public/bg.svg +++ /dev/null @@ -1,71 +0,0 @@ -<svg viewBox="0 0 1900 1000" xmlns="http://www.w3.org/2000/svg" fill="none" style=" - opacity:0.3; - --bg-base: rgb(20, 20, 20); - --accent-1:rgba(255, 90, 109, 0.56); - --accent-2:rgb(118, 56, 81); - --accent-3:rgb(198, 112, 78); - --accent-4:rgb(116, 0, 73); - --accent-5:rgb(112, 54, 47); - --accent-6:rgba(253, 39, 39, 0.32); - --accent-7:rgb(111, 37, 116); - "> - <defs> - <radialGradient gradientTransform="matrix(-381.8856201171875,-718.64599609375,1352.26904296875,-718.5903930664062,1460.033935546875,1616.3768310546875)" gradientUnits="userSpaceOnUse" r="1" cy="0" cx="0" id="paint3_radial"> - <stop stop-color="var(--bg-base)"/> - <stop stop-color="var(--bg-base)" offset="0.82292"/> - <stop stop-opacity="0" stop-color="var(--bg-base)" offset="1"/> - </radialGradient> - <radialGradient gradientTransform="matrix(-381.8856201171875,-718.64599609375,1352.26904296875,-718.5903930664062,1523.080078125,1511.2974853515625)" gradientUnits="userSpaceOnUse" r="1" cy="0" cx="0" id="paint4_radial"> - <stop stop-color="var(--bg-base)"/> - <stop stop-color="var(--bg-base)" offset="0.82292"/> - <stop stop-opacity="0" stop-color="var(--bg-base)" offset="1"/> - </radialGradient> - <radialGradient gradientTransform="matrix(-367.9964599609375,668.3052368164062,-775.7698364257812,-427.1709289550781,1491.2763671875,646.0341186523438)" gradientUnits="userSpaceOnUse" r="1" cy="0" cx="0" id="paint5_radial"> - <stop stop-color="var(--accent-1)" offset="0.32813"/> - <stop stop-opacity="0" stop-color="white" offset="1"/> - </radialGradient> - <radialGradient gradientTransform="matrix(-708.8882446289062,428.3532409667969,-802.1248168945312,-1340.3924560546875,1895.1649169921875,806.4420166015625)" gradientUnits="userSpaceOnUse" r="1" cy="0" cx="0" id="paint6_radial"> - <stop stop-color="var(--bg-base)"/> - <stop stop-color="var(--bg-base)" offset="0.78938"/> - <stop stop-opacity="0" stop-color="var(--bg-base)" offset="1"/> - </radialGradient> - <radialGradient gradientTransform="matrix(1168.929931640625,2499.95166015625,-2448.661865234375,1144.9478759765625,-137.4949951171875,-345.2243957519531)" gradientUnits="userSpaceOnUse" r="1" cy="0" cx="0" id="paint0_radial"> - <stop stop-color="var(--bg-base)"/> - <stop stop-color="var(--accent-1)" offset="0.08333"/> - <stop stop-color="var(--accent-2)" offset="0.36458"/> - <stop stop-color="var(--bg-base)" offset="0.65804"/> - <stop stop-color="var(--accent-3)" offset="0.79852"/> - <stop stop-color="var(--bg-base)" offset="0.94271"/> - <stop stop-color="var(--bg-base)" offset="1"/> - </radialGradient> - <radialGradient gradientTransform="matrix(1168.929931640625,2499.95166015625,-2448.661865234375,1144.9478759765625,293.6920166015625,64.984619140625)" gradientUnits="userSpaceOnUse" r="1" cy="0" cx="0" id="paint1_radial"> - <stop stop-color="var(--bg-base)"/> - <stop stop-color="var(--accent-4)" offset="0.08333"/> - <stop stop-color="var(--accent-5)" offset="0.3338"/> - <stop stop-color="var(--bg-base)" offset="0.65804"/> - <stop stop-color="var(--accent-3)" offset="0.79852"/> - <stop stop-color="var(--bg-base)" offset="0.94271"/> - <stop stop-color="var(--bg-base)" offset="1"/> - </radialGradient> - <radialGradient gradientTransform="matrix(1168.929931640625,2499.95166015625,-2448.661865234375,1144.9478759765625,598.625732421875,180.31497192382812)" gradientUnits="userSpaceOnUse" r="1" cy="0" cx="0" id="paint2_radial"> - <stop stop-color="var(--bg-base)"/> - <stop stop-opacity="0" stop-color="var(--accent-6)" offset="0.14063"/> - <stop stop-color="var(--accent-7)" offset="0.3338"/> - <stop stop-color="var(--bg-base)" offset="0.65804"/> - <stop stop-color="var(--accent-3)" offset="0.79852"/> - <stop stop-color="var(--bg-base)" offset="0.94271"/> - <stop stop-color="var(--bg-base)" offset="1"/> - </radialGradient> - </defs> - <g> - <g id="svg_1"> - <path id="svg_2" fill="url(#paint0_radial)" d="m1502.44912,585.67754c33.10025,39.73622 61.75559,56.73205 38.47076,89.01439c-207.12817,287.18063 -533.50156,932.74603 -749.82619,1033.23391c-875.97368,290.34215 -1794.58437,-383.1195 -929.17869,-874.49315c865.40612,-491.37708 -320.65596,-399.01561 171.18459,-730.25605c572.8894,-385.82665 1337.65958,210.53419 1469.34952,482.5009z"/> - <path id="svg_3" fill="url(#paint1_radial)" d="m587.07817,485.4941l419.66703,159.06733c24.18089,9.16687 41.4162,25.71878 46.94265,45.09221l69.01414,241.88691l313.39974,-96.93921c25.09839,-7.76404 53.68243,-6.95072 77.8676,2.21572l419.66703,159.06737c44.52885,16.87946 61.75559,56.73076 38.47076,89.01482l-111.72942,154.90774c-9.73238,13.49242 -25.6043,24.12944 -44.92329,30.10606l-547.85575,169.45915l120.53144,422.44097c4.32598,15.15593 1.1576,30.93353 -8.9435,44.57172l-156.90567,211.74998l-496.69002,-188.26365c-24.18518,-9.16644 -41.4162,-25.71577 -46.94265,-45.0905c-121.18569,-424.72615 -163.28659,-464.9033 -346.7638,-1107.95457c-17.09383,-59.91029 10.94014,-95.04032 20.67252,-108.5336l111.72985,-154.90851c23.28397,-32.28243 78.25947,-44.76903 122.79132,-27.88995z"/> - <path id="svg_4" fill="url(#paint2_radial)" d="m892.01032,600.82489l419.66703,159.06737c24.18518,9.16644 41.4162,25.71835 46.94265,45.09178l69.01843,241.88605l313.39546,-96.93792c25.10268,-7.76447 53.68672,-6.95072 77.8676,2.21572l419.66703,159.06737c44.53314,16.87946 61.75559,56.73076 38.47076,89.01482l-111.72942,154.90774c-9.73238,13.49242 -25.6043,24.12944 -44.92329,30.10606l-547.85146,169.45915l120.53144,422.44097c4.32169,15.15593 1.1576,30.93353 -8.94779,44.57172l-156.90567,211.74998l-496.69002,-188.26365c-24.18518,-9.16644 -41.4162,-25.71577 -46.94265,-45.0905l-69.01414,-241.88605l-313.40017,96.93792c-25.10096,7.76447 -53.68414,6.94986 -77.86803,-2.21658c0,0 -435.59683,-164.42146 -346.34633,-402.50031c89.25033,-238.07456 341.27735,-122.28069 592.71786,-200.05397l-120.6472,-422.84656c-4.25738,-14.91069 -1.26478,-30.42933 8.4676,-43.92261l111.72942,-154.9086c23.28482,-32.28234 78.26204,-44.76894 122.79089,-27.88991z"/> - <path id="svg_5" fill="url(#paint3_radial)" d="m484.48046,2237.81313l-319.39785,-1215.0982l2173.29209,-725.58785l1371.32646,1940.68605l-3225.2207,0z"/> - <path id="svg_6" fill="url(#paint4_radial)" d="m547.5287,2132.73345l-319.39798,-1215.0982l2173.29007,-725.58785l1371.32646,1940.68605l-3225.21855,0z"/> - <ellipse id="svg_7" fill="url(#paint5_radial)" ry="668.30572" rx="728.49213" cy="646.03415" cx="1234.93732"/> - <path id="svg_8" fill="url(#paint6_radial)" d="m2824.13444,684.91842l-1735.35896,1585.86861l-837.3177,-2104.40458l1818.07193,-1439.64029l754.60472,1958.17626z" opacity="0.5"/> - </g> - </g> -</svg> \ No newline at end of file diff --git a/src/components/onboarding/wallets/keychain/KeychainConnect.vue b/src/components/onboarding/wallets/keychain/KeychainConnect.vue index 1abdcdb48bb1ad2f2ad8cbe62e341ecd529b251e..751e19133122db5d5a579c84b871496f5bb53d9e 100644 --- a/src/components/onboarding/wallets/keychain/KeychainConnect.vue +++ b/src/components/onboarding/wallets/keychain/KeychainConnect.vue @@ -6,6 +6,7 @@ import { ref } from 'vue'; import { mdiClose } from '@mdi/js'; import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { UsedWallet, getWalletIcon } from '@/stores/settings.store'; +import { toastError } from "@/utils/parse-error"; const emit = defineEmits(["setaccount", "close"]); @@ -14,13 +15,11 @@ const close = () => { }; const isLoading = ref(false); -const errorMsg = ref<string | null>(null); const selectedLevel = ref<string | null>('posting'); const connect = async() => { try { isLoading.value = true; - errorMsg.value = null; const response = await new Promise((resolve, reject) => { (window as any).hive_keychain.requestSignBuffer( @@ -40,10 +39,7 @@ const connect = async() => { emit("setaccount", response.data.username); } catch (error) { - if (typeof error === "object" && error && "message" in error) - errorMsg.value = error.message as string; - else - errorMsg.value = String(error); + toastError('Failed to connect to Keychain', error); } finally { isLoading.value = false; } @@ -97,7 +93,6 @@ const connect = async() => { </div> </CardContent> <CardFooter> - <span class="text-red-400" v-if="errorMsg"><span class="font-bold">Error: </span>{{ errorMsg }}</span> </CardFooter> </Card> </template> diff --git a/src/components/onboarding/wallets/metamask/MetamaskConnect.vue b/src/components/onboarding/wallets/metamask/MetamaskConnect.vue index 649db7e14faf02ebc1d40eee2febdcbc2ce0f60f..b71a366ba719edcd1f9be8744bc22ed1ffbe2f93 100644 --- a/src/components/onboarding/wallets/metamask/MetamaskConnect.vue +++ b/src/components/onboarding/wallets/metamask/MetamaskConnect.vue @@ -12,6 +12,7 @@ import { useMetamaskStore } from "@/stores/metamask.store"; import { Combobox, ComboboxAnchor, ComboboxTrigger, ComboboxEmpty, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxItemIndicator, ComboboxList } from '@/components/ui/combobox'; import { Check, Search } from 'lucide-vue-next'; import { Separator } from '@/components/ui/separator'; +import { toastError } from "@/utils/parse-error"; import PublicKey from '@/components/hive/PublicKey.vue'; import { Checkbox } from '@/components/ui/checkbox' import { getWax } from '@/stores/wax.store'; @@ -38,7 +39,6 @@ const close = () => { const metamaskStore = useMetamaskStore(); const isLoading = ref(false); -const errorMsg = ref<string | null>(null); const accountName = ref<string | null>(null); const createAccountNameOperation = ref<string | null>(null); const updateAccountNameOperation = ref<string | null>(null); @@ -49,7 +49,6 @@ const isMetamaskSnapInstalled = ref<boolean>(false); const applyPublicKeys = async () => { isLoading.value = true; - errorMsg.value = null; try { const { publicKeys } = await metamaskStore.call("hive_getPublicKeys", { keys: [{ @@ -73,10 +72,7 @@ const applyPublicKeys = async () => { accountsMatchingKeys.value = [...new Set(response.accounts.flatMap((node: string[]) => node))] as string[]; } catch (error) { - if (typeof error === "object" && error && "message" in error) - errorMsg.value = error.message as string; - else - errorMsg.value = String(error); + toastError("Failed to match Metamask public keys", error); } finally { isLoading.value = false; } @@ -85,20 +81,23 @@ const applyPublicKeys = async () => { const accountNameValid = ref(false); const validateAccountName = async() => { - if(!createAccountNameOperation.value) - return accountNameValid.value = false; + try { + if(!createAccountNameOperation.value) + return accountNameValid.value = false; - const accountName = createAccountNameOperation.value.startsWith("@") ? createAccountNameOperation.value.slice(1) : createAccountNameOperation.value; - if (!accountName) - return accountNameValid.value = false; + const accountName = createAccountNameOperation.value.startsWith("@") ? createAccountNameOperation.value.slice(1) : createAccountNameOperation.value; + if (!accountName) + return accountNameValid.value = false; - const wax = await getWax(); - return accountNameValid.value = wax.isValidAccountName(accountName); + const wax = await getWax(); + return accountNameValid.value = wax.isValidAccountName(accountName); + } catch (error) { + toastError("Failed to validate account name", error); + } } const connect = async (showError = true) => { isLoading.value = true; - errorMsg.value = null; try { await metamaskStore.connect(); @@ -110,10 +109,7 @@ const connect = async (showError = true) => { if (!showError) return; - if (typeof error === "object" && error && "message" in error) - errorMsg.value = error.message as string; - else - errorMsg.value = String(error); + toastError("Failed to connect to Metamask", error); } finally { isLoading.value = false; }; @@ -121,7 +117,6 @@ const connect = async (showError = true) => { const install = async () => { isLoading.value = true; - errorMsg.value = null; try { await metamaskStore.install(); isMetamaskSnapInstalled.value = metamaskStore.isInstalled!; @@ -129,10 +124,7 @@ const install = async () => { if (isMetamaskSnapInstalled.value) void applyPublicKeys(); } catch (error) { - if (typeof error === "object" && error && "message" in error) - errorMsg.value = error.message as string; - else - errorMsg.value = String(error); + toastError("Failed to install Metamask Snap", error); } finally { isLoading.value = false; }; @@ -142,21 +134,25 @@ onMounted(() => { void connect(false); }); -const generateAccountUpdateTransaction = async(): Promise<string> => { - const wax = await getWax(); - const tx = await wax.createTransaction(); - const accountName = updateAccountNameOperation.value!.startsWith('@') ? updateAccountNameOperation.value!.slice(1) : updateAccountNameOperation.value!; - const { AccountAuthorityUpdateOperation } = await import("@hiveio/wax/vite"); - const op = await AccountAuthorityUpdateOperation.createFor(wax, accountName); - for(const key in updateAuthType) { - if (updateAuthType[key as TRole]) - if (key === "memo") - op.role("memo").set(metamaskPublicKeys.value!.find(node => node.role === key)!.publicKey); - else - op.role(key as Exclude<TRole, "memo">).add(metamaskPublicKeys.value!.find(node => node.role === key)!.publicKey); - } - tx.pushOperation(op); - return tx.toApi(); +const generateAccountUpdateTransaction = async(): Promise<string | void> => { + try { + const wax = await getWax(); + const tx = await wax.createTransaction(); + const accountName = updateAccountNameOperation.value!.startsWith('@') ? updateAccountNameOperation.value!.slice(1) : updateAccountNameOperation.value!; + const { AccountAuthorityUpdateOperation } = await import("@hiveio/wax/vite"); + const op = await AccountAuthorityUpdateOperation.createFor(wax, accountName); + for(const key in updateAuthType) { + if (updateAuthType[key as TRole]) + if (key === "memo") + op.role("memo").set(metamaskPublicKeys.value!.find(node => node.role === key)!.publicKey); + else + op.role(key as Exclude<TRole, "memo">).add(metamaskPublicKeys.value!.find(node => node.role === key)!.publicKey); + } + tx.pushOperation(op); + return tx.toApi(); + } catch (error) { + toastError("Failed to generate account update transaction", error); + } }; const getAccountCreateSigningLink = (): string => { const accountName = createAccountNameOperation.value!.startsWith('@') ? createAccountNameOperation.value!.slice(1) : createAccountNameOperation.value!; @@ -358,7 +354,6 @@ const updateAccountName = (value: string | any) => { </div> </CardContent> <CardFooter> - <span class="text-red-400" v-if="errorMsg"><span class="font-bold">Error: </span>{{ errorMsg }}</span> </CardFooter> </Card> </template> diff --git a/src/components/onboarding/wallets/peakvault/PeakVaultConnect.vue b/src/components/onboarding/wallets/peakvault/PeakVaultConnect.vue index 27bfa11325c22e4fcd26a15fc5b6ee813d8bafcf..5893c2f381ca06872bf9f37414740ab5959e6f64 100644 --- a/src/components/onboarding/wallets/peakvault/PeakVaultConnect.vue +++ b/src/components/onboarding/wallets/peakvault/PeakVaultConnect.vue @@ -5,6 +5,7 @@ import step1 from "@/assets/icons/wallets/peakvault/step1.webp"; import { ref } from 'vue'; import { mdiClose } from '@mdi/js'; import { UsedWallet, getWalletIcon } from '@/stores/settings.store'; +import { toastError } from "@/utils/parse-error"; const emit = defineEmits(["setaccount", "close"]); @@ -13,20 +14,15 @@ const close = () => { }; const isLoading = ref(false); -const errorMsg = ref<string | null>(null); const connect = async() => { try { isLoading.value = true; - errorMsg.value = null; const { result } = await (window as any).peakvault.requestContact(); emit("setaccount", result as string); } catch (error) { - if (typeof error === "object" && error && "message" in error) - errorMsg.value = error.message as string; - else - errorMsg.value = String(error); + toastError('Failed to connect to PeakVault', error); } finally { isLoading.value = false; } @@ -66,7 +62,6 @@ const connect = async() => { </div> </CardContent> <CardFooter> - <span class="text-red-400" v-if="errorMsg"><span class="font-bold">Error: </span>{{ errorMsg }}</span> </CardFooter> </Card> </template> diff --git a/src/components/ui/button/Button.vue b/src/components/ui/button/Button.vue index ba01e17dceb546df0d75194e598e4e3f5fc8db23..7514b91ae4f57be8d38683e5c3b8eed184b8dc1a 100644 --- a/src/components/ui/button/Button.vue +++ b/src/components/ui/button/Button.vue @@ -12,7 +12,7 @@ interface Props extends PrimitiveProps { class?: HTMLAttributes['class'] loading?: boolean disabled?: boolean - copy?: string | (() => (string | Promise<string>)) + copy?: string | (() => (string | void | Promise<string | void>)) } const props = withDefaults(defineProps<Props>(), { @@ -25,13 +25,19 @@ const copyLoading = ref(false); const copyBtn = () => { if (!props.copy) return; const text = typeof props.copy === 'function' ? props.copy() : props.copy; + let copied = false; + if(text instanceof Promise) text.then((text) => { - copyText(text); + if (copied = !!text) + copyText(text); }); - else + else if (copied = !!text) copyText(text); + if (!copied) + return; + copyLoading.value = true; setTimeout(() => { copyLoading.value = false;