From 38201bb25456f2ee65f00a16ee159ed47c5f24e8 Mon Sep 17 00:00:00 2001 From: Jefferson Mantovani Date: Thu, 6 Nov 2025 10:28:14 -0300 Subject: [PATCH] feat: versioning --- src/App.vue | 8 - src/components/TopBar/TopBar.vue | 322 +++++++++++++++++++++---------- src/model/AppVersion.ts | 8 + src/router/index.ts | 6 + src/utils/versions.ts | 24 +++ src/views/VersionsView.vue | 156 +++++++++++++++ vite.config.ts | 14 +- 7 files changed, 421 insertions(+), 117 deletions(-) create mode 100644 src/model/AppVersion.ts create mode 100644 src/utils/versions.ts create mode 100644 src/views/VersionsView.vue diff --git a/src/App.vue b/src/App.vue index 5aed1b2..3912542 100644 --- a/src/App.vue +++ b/src/App.vue @@ -12,9 +12,6 @@ const route = useRoute(); const injected = injectedModule(); const targetNetwork = ref(DEFAULT_NETWORK); -const currentYear = new Date().getFullYear(); -const appVersion = __APP_VERSION__; - const web3Onboard = init({ wallets: [injected], chains: Object.values(Networks).map((network) => ({ @@ -57,9 +54,4 @@ if (!connectedWallet) { -
-
-

Versão: {{ appVersion }} | © {{ currentYear }} P2Pix. Todos os direitos reservados.

-
-
diff --git a/src/components/TopBar/TopBar.vue b/src/components/TopBar/TopBar.vue index 518b468..c203379 100644 --- a/src/components/TopBar/TopBar.vue +++ b/src/components/TopBar/TopBar.vue @@ -14,6 +14,18 @@ import { connectProvider } from "@/blockchain/provider"; import { DEFAULT_NETWORK } from "@/config/networks"; import type { NetworkConfig } from "@/model/NetworkEnum"; +interface MenuOption { + label: string; + route?: string; + action?: () => void; + showInDesktop?: boolean; + showInMobile?: boolean; + isDynamic?: boolean; + dynamicLabel?: () => string; + dynamicRoute?: () => string; + showVersion?: boolean; +} + // Use the new composable const user = useUser(); const { walletAddress, sellerView, network } = user; @@ -80,15 +92,22 @@ const closeMenu = (): void => { const networkChange = async (network: NetworkConfig): Promise => { currencyMenuOpenToggle.value = false; - const chainId = network.id.toString(16) - try { - await setChain({ - chainId: `0x${chainId}`, - wallet: connectedWallet.value?.label || "", - }); + + // If wallet is connected, try to change chain in wallet + if (connectedWallet.value) { + const chainId = network.id.toString(16) + try { + await setChain({ + chainId: `0x${chainId}`, + wallet: connectedWallet.value.label, + }); + user.setNetwork(network); + } catch (error) { + console.log("Error changing network", error); + } + } else { + // If no wallet connected, just update the network state user.setNetwork(network); - } catch (error) { - console.log("Error changing network", error); } }; @@ -103,11 +122,80 @@ onClickOutside(currencyRef, () => { onClickOutside(infoMenuRef, () => { infoMenuOpenToggle.value = false; }); + +const infoMenuOptions: MenuOption[] = [ + { + label: "Explorar Transações", + route: "/explore", + showInDesktop: true, + showInMobile: false, + }, + { + label: "Perguntas frequentes", + route: "/faq", + showInDesktop: true, + showInMobile: false, + }, + { + label: "Versões", + route: "/versions", + showInDesktop: true, + showInMobile: false, + }, +]; + +const walletMenuOptions: MenuOption[] = [ + { + label: "Quero vender", + isDynamic: true, + dynamicLabel: () => (sellerView.value ? "Quero comprar" : "Quero vender"), + dynamicRoute: () => (sellerView.value ? "/" : "/seller"), + showInDesktop: false, + showInMobile: true, + }, + { + label: "Explorar Transações", + route: "/explore", + showInDesktop: false, + showInMobile: true, + }, + { + label: "Gerenciar Ofertas", + route: "/manage_bids", + showInDesktop: true, + showInMobile: true, + }, + { + label: "Perguntas frequentes", + route: "/faq", + showInDesktop: false, + showInMobile: true, + }, + { + label: "Versões", + route: "/versions", + showInDesktop: false, + showInMobile: true, + }, + { + label: "Desconectar", + route: "/", + action: disconnectUser, + showInDesktop: true, + showInMobile: true, + }, +]; + +const handleMenuOptionClick = (option: MenuOption): void => { + if (!option.action) { + closeMenu(); + } +};

@@ -233,13 +326,6 @@ onClickOutside(infoMenuRef, () => { - - FAQ - - - - -
+
{
@@ -412,35 +506,49 @@ onClickOutside(infoMenuRef, () => { v-show="menuOpenToggle" class="mobile-menu fixed w-4/5 text-gray-900 inline-block md:hidden" > -
+
- +

@@ -474,7 +582,7 @@ onClickOutside(infoMenuRef, () => { v-show="currencyMenuOpenToggle" class="mobile-menu fixed w-4/5 text-gray-900 inline-block md:hidden" > -
+
diff --git a/src/model/AppVersion.ts b/src/model/AppVersion.ts new file mode 100644 index 0000000..0272dd5 --- /dev/null +++ b/src/model/AppVersion.ts @@ -0,0 +1,8 @@ +export interface AppVersion { + tag: string; + ipfsHash: string; + releaseDate: string; + description?: string; +} + + diff --git a/src/router/index.ts b/src/router/index.ts index a1ccc85..66bed9f 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -4,6 +4,7 @@ import FaqView from "@/views/FaqView.vue"; import ManageBidsView from "@/views/ManageBidsView.vue"; import SellerView from "@/views/SellerView.vue"; import ExploreView from "@/views/ExploreView.vue"; +import VersionsView from "@/views/VersionsView.vue"; const router = createRouter({ history: import.meta.env.MODE === 'production' && import.meta.env.BASE_URL === './' @@ -41,6 +42,11 @@ const router = createRouter({ name: "explore", component: ExploreView, }, + { + path: "/versions", + name: "versions", + component: VersionsView, + }, ], }); diff --git a/src/utils/versions.ts b/src/utils/versions.ts new file mode 100644 index 0000000..8ce31d7 --- /dev/null +++ b/src/utils/versions.ts @@ -0,0 +1,24 @@ +import type { AppVersion } from "@/model/AppVersion"; + +export const appVersions: AppVersion[] = [ + { + tag: "1.0.0", + ipfsHash: "bafybeiagfqnxnb5zdrks6dicfm7kxjdtzzzzm2ouluxgdseg2hrrotayzi", + releaseDate: "2023-01-28", + description: "Initial release" + }, +]; + +export function getLatestVersion(): AppVersion | null { + return appVersions.length > 0 ? appVersions[0] : null; +} + +export function getVersionByTag(tag: string): AppVersion | null { + return appVersions.find((v) => v.tag === tag) || null; +} + +export function getIpfsUrl(ipfsHash: string): string { + return `https://${ipfsHash}.ipfs.dweb.link`; +} + + diff --git a/src/views/VersionsView.vue b/src/views/VersionsView.vue new file mode 100644 index 0000000..43a8e89 --- /dev/null +++ b/src/views/VersionsView.vue @@ -0,0 +1,156 @@ + + + + + + + diff --git a/vite.config.ts b/vite.config.ts index 34dc68c..4501aec 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -6,11 +6,17 @@ import vue from "@vitejs/plugin-vue"; import vueJsx from "@vitejs/plugin-vue-jsx"; import svgLoader from "vite-svg-loader"; -function getGitCommitHash(): string { +function getGitTag(): string { try { - return execSync("git rev-parse --short HEAD").toString().trim(); + const tag = execSync("git describe --tags --abbrev=0").toString().trim(); + return tag || ""; } catch (error) { - return "unknown"; + try { + const tags = execSync("git tag --sort=-version:refname").toString().trim().split("\n"); + return tags.length > 0 ? tags[0] : "unknown"; + } catch (fallbackError) { + return ""; + } } } @@ -21,7 +27,7 @@ export default defineConfig({ target: "esnext", }, define: { - __APP_VERSION__: JSON.stringify(getGitCommitHash()), + __APP_VERSION__: JSON.stringify(getGitTag()), }, optimizeDeps: { esbuildOptions: {