Skip to content

Commit

Permalink
feat: add useVueDappModal for another approach to open the modal
Browse files Browse the repository at this point in the history
  • Loading branch information
johnson86tw committed Apr 19, 2024
1 parent d99bbb1 commit 6eea040
Show file tree
Hide file tree
Showing 13 changed files with 163 additions and 49 deletions.
44 changes: 22 additions & 22 deletions app/app.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts" setup>
import { BrowserWalletConnector, useVueDapp, type ConnWallet, VueDappProvider } from '@vue-dapp/core'
import { WalletConnectConnector } from '@vue-dapp/walletconnect'
import { CoinbaseWalletConnector } from '@vue-dapp/coinbase'
// import { WalletConnectConnector } from '@vue-dapp/walletconnect'
// import { CoinbaseWalletConnector } from '@vue-dapp/coinbase'
import { ethers } from 'ethers'
import { useDappStore } from '~/stores/dappStore'
import { VueDappModal } from '@vue-dapp/modal'
Expand All @@ -22,25 +22,25 @@ const { addConnectors } = useVueDapp()
if (process.client) {
addConnectors([
new BrowserWalletConnector(),
new WalletConnectConnector({
projectId: 'd1e65611568666138126d315c0bafd7d',
chains: [1],
showQrModal: true,
qrModalOptions: {
themeMode: 'light',
themeVariables: undefined,
desktopWallets: undefined,
walletImages: undefined,
mobileWallets: undefined,
enableExplorer: true,
privacyPolicyUrl: undefined,
termsOfServiceUrl: undefined,
},
}),
new CoinbaseWalletConnector({
appName: 'Vue Dapp',
jsonRpcUrl: `https://mainnet.infura.io/v3/${INFURA_ID}`,
}),
// new WalletConnectConnector({
// projectId: 'd1e65611568666138126d315c0bafd7d',
// chains: [1],
// showQrModal: true,
// qrModalOptions: {
// themeMode: 'light',
// themeVariables: undefined,
// desktopWallets: undefined,
// walletImages: undefined,
// mobileWallets: undefined,
// enableExplorer: true,
// privacyPolicyUrl: undefined,
// termsOfServiceUrl: undefined,
// },
// }),
// new CoinbaseWalletConnector({
// appName: 'Vue Dapp',
// jsonRpcUrl: `https://mainnet.infura.io/v3/${INFURA_ID}`,
// }),
])
}
Expand Down Expand Up @@ -74,7 +74,7 @@ function handleDisconnect() {
<NuxtPage />

<ClientOnly>
<VueDappModal v-model="dappStore.connectModalOpen" autoConnect />
<VueDappModal autoConnect />
</ClientOnly>
</VueDappProvider>
</NuxtLayout>
Expand Down
4 changes: 3 additions & 1 deletion app/components/button/ConnectButton.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script setup lang="ts">
import { useVueDapp, shortenAddress } from '@vue-dapp/core'
import { useVueDappModal } from '@vue-dapp/modal'
const { address, status, error, disconnect } = useVueDapp()
const dappStore = useDappStore()
Expand All @@ -9,7 +10,8 @@ function onClickConnectButton() {
disconnect()
return
}
dappStore.connectModalOpen = !dappStore.connectModalOpen
const { open } = useVueDappModal(useNuxtApp().$pinia)
open()
}
</script>

Expand Down
4 changes: 3 additions & 1 deletion app/components/dapp/ConnectButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { storeToRefs } from 'pinia'
import { shortenAddress, useVueDapp } from '@vue-dapp/core'
import copy from 'copy-to-clipboard'
import { useDappStore } from '~/stores/dappStore'
import { useVueDappModal } from '@vue-dapp/modal'
const { disconnect } = useVueDapp()
const { connector, status, address, isConnected } = useVueDapp()
Expand All @@ -11,7 +12,8 @@ const dappStore = useDappStore()
const { isNetworkUnmatched } = storeToRefs(dappStore)
function onClickConnectButton() {
dappStore.connectModalOpen = !dappStore.connectModalOpen
const { open } = useVueDappModal(useNuxtApp().$pinia)
open()
}
async function onSwitchChain() {
Expand Down
5 changes: 3 additions & 2 deletions app/pages/index.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script setup lang="ts">
import pkg from '~/package.json'
import { shortenAddress, useVueDapp } from '@vue-dapp/core'
import { useVueDappModal } from '@vue-dapp/modal'
import type { ConnWallet } from '@vue-dapp/core'
import { ethers, formatEther } from 'ethers'
Expand All @@ -12,7 +13,6 @@ useHead({
const defaultProvider = new ethers.JsonRpcProvider('https://ethereum-rpc.publicnode.com')
const { wallet, isConnected, disconnect, onWalletUpdated, onDisconnected } = useVueDapp()
const dappStore = useDappStore()
const ensName = ref('')
async function fetchENSName(address: string) {
Expand Down Expand Up @@ -42,7 +42,8 @@ function onClickConnectButton() {
disconnect()
return
}
dappStore.connectModalOpen = !dappStore.connectModalOpen
const { open } = useVueDappModal(useNuxtApp().$pinia)
open()
}
</script>

Expand Down
2 changes: 0 additions & 2 deletions app/stores/dappStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { HARDHAT_PRIV_KEY, MULTICALL3_ADDRESS } from '@/constants'
import { networkMap, type AppNetwork } from '@/constants'

export type DappState = {
connectModalOpen: boolean
user: User
network: AppNetwork
blockNumber: number
Expand All @@ -23,7 +22,6 @@ export const networkOptions = [...networkMap.keys()]

export const useDappStore = defineStore('dapp', {
state: (): DappState => ({
connectModalOpen: false,
user: {
address: '',
signer: null,
Expand Down
38 changes: 37 additions & 1 deletion packages/modal/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,39 @@
# @vue-dapp/modal

<a href="https://www.npmjs.com/package/@vue-dapp/modal"><img src="https://badgen.net/npm/v/@vue-dapp/modal" alt="Version"></a>
<a href="https://www.npmjs.com/package/@vue-dapp/modal"><img src="https://badgen.net/npm/v/@vue-dapp/modal" alt="Version"></a>



## Two approach to open/close the modal

### v-model

```ts
const isModalOpen = ref(false)

```

Must add `v-model`
```vue
<VueDappModal
v-model="isModalOpen"
autoConnect
/>
```

### pinia store

- only works with SPA

```ts
import { useVueDappStore } from '@vue-dapp/modal'

const { open, close } = useVueDappStore()
```

Don't add `v-model`
```vue
<VueDappModal
autoConnect
/>
```
3 changes: 2 additions & 1 deletion packages/modal/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@
},
"peerDependencies": {
"@vue-dapp/core": "*",
"vue": "^3.3.6"
"vue": ">=3.3.6",
"pinia": ">=2.1.7"
},
"gitHead": "32a6d53db2bd674115648f41c80582140175c25b"
}
8 changes: 7 additions & 1 deletion packages/modal/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
import { ref } from 'vue'
import { BrowserWalletConnector, useVueDapp } from '@vue-dapp/core'
import VueDappModal from './VueDappModal.vue'
import { useVueDappModal } from './store'
const store = useVueDappModal()
const isModalOpen = ref(false)
Expand All @@ -12,6 +15,7 @@ addConnector(new BrowserWalletConnector())
function onClickConnectButton() {
if (!isConnected.value) {
isModalOpen.value = true
// store.open()
} else {
disconnect()
}
Expand All @@ -28,14 +32,16 @@ function autoConnectErrorHandler(err: any) {
<template>
<div>
<button @click="onClickConnectButton">{{ isConnected ? 'Disconnect' : 'Connect Wallet' }}</button>
<button @click="store.open">open</button>

<div>{{ error }}</div>
<p v-if="chainId">Chain ID: {{ chainId }}</p>
<p>{{ address }}</p>

<VueDappModal
v-model="isModalOpen"
autoConnect
autoConnectBrowserWalletIfSolo
:autoConnectBrowserWalletIfSolo="false"
dark
:connectErrorHandler="connectErrorHandler"
:autoConnectErrorHandler="autoConnectErrorHandler"
Expand Down
41 changes: 24 additions & 17 deletions packages/modal/src/VueDappModal.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
<script setup lang="ts">
import { onMounted, ref, watch } from 'vue'
import { computed, onMounted, ref, watch } from 'vue'
import Modal from './components/Modal.vue'
import WalletConnectIcon from './components/logos/WalletConnectIcon.vue'
import { useVueDapp, ConnectorName, RDNS } from '@vue-dapp/core'
import { useVueDappModal } from './store'
const props = withDefaults(
defineProps<{
modelValue: boolean
modelValue?: boolean | undefined
dark?: boolean
autoConnect?: boolean
connectTimeout?: number
Expand All @@ -15,6 +16,7 @@ const props = withDefaults(
autoConnectErrorHandler?: (err: any) => void
}>(),
{
modelValue: undefined,
dark: false,
autoConnect: false,
connectTimeout: 0,
Expand All @@ -26,10 +28,18 @@ const props = withDefaults(
const emit = defineEmits(['update:modelValue'])
const store = useVueDappModal()
function closeModal() {
emit('update:modelValue', false)
if (props.modelValue === undefined) {
store.close()
} else {
emit('update:modelValue', false)
}
}
const modalOpen = computed(() => props.modelValue ?? store.isModalOpen)
const isAutoConnecting = ref(false)
const { connectors, connectTo, autoConnect, status, providerDetails, hasConnector, disconnect } = useVueDapp()
Expand All @@ -56,20 +66,17 @@ async function handleAutoConnect() {
onMounted(async () => handleAutoConnect())
// ============================ feat: auto click BrowserWallet if it's the only connector ============================
watch(
() => props.modelValue,
async () => {
if (props.autoConnectBrowserWalletIfSolo && props.modelValue) {
if (
connectors.value.length === 1 && // only one connector
providerDetails.value.length === 1 && // only one browser provider
connectors.value[0].name === 'BrowserWallet'
) {
await onClickWallet(connectors.value[0].name)
}
watch(modalOpen, async () => {
if (props.autoConnectBrowserWalletIfSolo && modalOpen.value) {
if (
connectors.value.length === 1 && // only one connector
providerDetails.value.length === 1 && // only one browser provider
connectors.value[0].name === 'BrowserWallet'
) {
await onClickWallet(connectors.value[0].name)
}
},
)
}
})
async function onClickWallet(connName: ConnectorName, rdns?: RDNS | string) {
try {
Expand Down Expand Up @@ -113,7 +120,7 @@ const vClickOutside = {

<template>
<div>
<Modal :modalOpen="modelValue" @close="closeModal" :dark="dark">
<Modal :modalOpen="modalOpen" @close="closeModal" :dark="dark">
<div id="vd-modal" v-click-outside="closeModal">
<div
v-for="detail in providerDetails"
Expand Down
2 changes: 2 additions & 0 deletions packages/modal/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
import VueDappModal from './VueDappModal.vue'
export { VueDappModal }

export * from './store'
20 changes: 20 additions & 0 deletions packages/modal/src/store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { ref } from 'vue'
import { defineStore } from 'pinia'

export const useVueDappModal = defineStore('vd-modal-store', () => {
const isModalOpen = ref(false)

function open() {
isModalOpen.value = true
}

function close() {
isModalOpen.value = false
}

return {
isModalOpen,
open,
close,
}
})
3 changes: 2 additions & 1 deletion packages/modal/vite.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ export default defineConfig({
},
outDir: 'dist',
rollupOptions: {
external: ['vue', '@vue-dapp/core'],
external: ['vue', 'pinia', '@vue-dapp/core'],
output: {
dir: 'dist',
globals: {
vue: 'vue',
pinia: 'pinia',
'@vue-dapp/core': 'core',
},
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// vite.config.mjs
import { defineConfig } from "file:///Users/johnson/vue-dapp/node_modules/.pnpm/vite@5.2.9_sass@1.70.0/node_modules/vite/dist/node/index.js";
import vue from "file:///Users/johnson/vue-dapp/node_modules/.pnpm/@vitejs+plugin-vue@5.0.3_vite@5.2.9_vue@3.4.21/node_modules/@vitejs/plugin-vue/dist/index.mjs";
import path from "path";
import dts from "file:///Users/johnson/vue-dapp/node_modules/.pnpm/vite-plugin-dts@3.7.2_typescript@5.3.3_vite@5.2.9/node_modules/vite-plugin-dts/dist/index.mjs";
var __vite_injected_original_dirname = "/Users/johnson/vue-dapp/packages/modal";
var vite_config_default = defineConfig({
plugins: [
vue(),
dts({
insertTypesEntry: true
})
],
build: {
assetsDir: "assets",
lib: {
entry: path.resolve(__vite_injected_original_dirname, "src/index.ts"),
name: "@vue-dapp/modal",
fileName: "modal"
},
outDir: "dist",
rollupOptions: {
external: ["vue", "pinia", "@vue-dapp/core"],
output: {
dir: "dist",
globals: {
vue: "vue",
pinia: "pinia",
"@vue-dapp/core": "core"
}
}
}
}
});
export {
vite_config_default as default
};
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcubWpzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZGlybmFtZSA9IFwiL1VzZXJzL2pvaG5zb24vdnVlLWRhcHAvcGFja2FnZXMvbW9kYWxcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcIi9Vc2Vycy9qb2huc29uL3Z1ZS1kYXBwL3BhY2thZ2VzL21vZGFsL3ZpdGUuY29uZmlnLm1qc1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vVXNlcnMvam9obnNvbi92dWUtZGFwcC9wYWNrYWdlcy9tb2RhbC92aXRlLmNvbmZpZy5tanNcIjtpbXBvcnQgeyBkZWZpbmVDb25maWcgfSBmcm9tICd2aXRlJ1xuaW1wb3J0IHZ1ZSBmcm9tICdAdml0ZWpzL3BsdWdpbi12dWUnXG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJ1xuaW1wb3J0IGR0cyBmcm9tICd2aXRlLXBsdWdpbi1kdHMnXG5cbmV4cG9ydCBkZWZhdWx0IGRlZmluZUNvbmZpZyh7XG5cdHBsdWdpbnM6IFtcblx0XHR2dWUoKSxcblx0XHRkdHMoe1xuXHRcdFx0aW5zZXJ0VHlwZXNFbnRyeTogdHJ1ZSxcblx0XHR9KSxcblx0XSxcblx0YnVpbGQ6IHtcblx0XHRhc3NldHNEaXI6ICdhc3NldHMnLFxuXHRcdGxpYjoge1xuXHRcdFx0ZW50cnk6IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICdzcmMvaW5kZXgudHMnKSxcblx0XHRcdG5hbWU6ICdAdnVlLWRhcHAvbW9kYWwnLFxuXHRcdFx0ZmlsZU5hbWU6ICdtb2RhbCcsXG5cdFx0fSxcblx0XHRvdXREaXI6ICdkaXN0Jyxcblx0XHRyb2xsdXBPcHRpb25zOiB7XG5cdFx0XHRleHRlcm5hbDogWyd2dWUnLCAncGluaWEnLCAnQHZ1ZS1kYXBwL2NvcmUnXSxcblx0XHRcdG91dHB1dDoge1xuXHRcdFx0XHRkaXI6ICdkaXN0Jyxcblx0XHRcdFx0Z2xvYmFsczoge1xuXHRcdFx0XHRcdHZ1ZTogJ3Z1ZScsXG5cdFx0XHRcdFx0cGluaWE6ICdwaW5pYScsXG5cdFx0XHRcdFx0J0B2dWUtZGFwcC9jb3JlJzogJ2NvcmUnLFxuXHRcdFx0XHR9LFxuXHRcdFx0fSxcblx0XHR9LFxuXHR9LFxufSlcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBc1MsU0FBUyxvQkFBb0I7QUFDblUsT0FBTyxTQUFTO0FBQ2hCLE9BQU8sVUFBVTtBQUNqQixPQUFPLFNBQVM7QUFIaEIsSUFBTSxtQ0FBbUM7QUFLekMsSUFBTyxzQkFBUSxhQUFhO0FBQUEsRUFDM0IsU0FBUztBQUFBLElBQ1IsSUFBSTtBQUFBLElBQ0osSUFBSTtBQUFBLE1BQ0gsa0JBQWtCO0FBQUEsSUFDbkIsQ0FBQztBQUFBLEVBQ0Y7QUFBQSxFQUNBLE9BQU87QUFBQSxJQUNOLFdBQVc7QUFBQSxJQUNYLEtBQUs7QUFBQSxNQUNKLE9BQU8sS0FBSyxRQUFRLGtDQUFXLGNBQWM7QUFBQSxNQUM3QyxNQUFNO0FBQUEsTUFDTixVQUFVO0FBQUEsSUFDWDtBQUFBLElBQ0EsUUFBUTtBQUFBLElBQ1IsZUFBZTtBQUFBLE1BQ2QsVUFBVSxDQUFDLE9BQU8sU0FBUyxnQkFBZ0I7QUFBQSxNQUMzQyxRQUFRO0FBQUEsUUFDUCxLQUFLO0FBQUEsUUFDTCxTQUFTO0FBQUEsVUFDUixLQUFLO0FBQUEsVUFDTCxPQUFPO0FBQUEsVUFDUCxrQkFBa0I7QUFBQSxRQUNuQjtBQUFBLE1BQ0Q7QUFBQSxJQUNEO0FBQUEsRUFDRDtBQUNELENBQUM7IiwKICAibmFtZXMiOiBbXQp9Cg==

0 comments on commit 6eea040

Please sign in to comment.