improve UX & adding links

This commit is contained in:
liangping 2023-05-20 08:07:36 +08:00
parent 1577e0a8ed
commit 32014f4a24
9 changed files with 110 additions and 46 deletions

17
public/test.html Normal file
View File

@ -0,0 +1,17 @@
<html>
<head>
<title>Widget Test</title>
<script src="https://unpkg.com/ping-widget@latest/dist/ping-widget.js" type="module" ></script>
</head>
<body>
<div class="p-5">
<div>
<ping-connect-wallet chain-id="kava_2222-10" hd-path="m/44'/118/0'/0/0"/>
</div>
<div>
<label for="PingTokenConvert" class="btn">Buy Kava</label>
<ping-token-convert chain-name="kava" endpoint="https://api.data.kava.io" hd-path="m/44'/118/0'/0/0"/>
</div>
</div>
</body>
</html>

View File

@ -13,6 +13,7 @@ import { useDashboard } from '@/stores/useDashboard';
import NavBarI18n from './NavBarI18n.vue'; import NavBarI18n from './NavBarI18n.vue';
import NavBarWallet from './NavBarWallet.vue'; import NavBarWallet from './NavBarWallet.vue';
import { useBlockchain } from '@/stores'; import { useBlockchain } from '@/stores';
import { computed } from 'vue';
const { appRouteTransition } = useThemeConfig(); const { appRouteTransition } = useThemeConfig();
@ -34,6 +35,7 @@ const changeOpen = (index: Number) => {
sidebarOpen.value = !sidebarOpen.value; sidebarOpen.value = !sidebarOpen.value;
} }
}; };
const showDiscord = window.location.host.search("ping.pub") > -1
</script> </script>
<template> <template>
@ -92,7 +94,7 @@ const changeOpen = (index: Number) => {
</div> </div>
<div <div
v-if="item?.badgeContent" v-if="item?.badgeContent"
class="mr-6 badge badge-sm badge-primary" class="mr-6 badge badge-sm rounded-none" :class="item?.badgeClass"
> >
{{ item?.badgeContent }} {{ item?.badgeContent }}
</div> </div>
@ -137,7 +139,7 @@ const changeOpen = (index: Number) => {
<RouterLink <RouterLink
:to="item?.to" :to="item?.to"
v-if="item?.title && !item?.children?.length" v-if="item?.title && !item?.children?.length && item?.to"
@click="sidebarShow = false" @click="sidebarShow = false"
class="collapse-title px-4 flex items-center py-2 hover:bg-gray-100 dark:hover:bg-[#373f59]" class="collapse-title px-4 flex items-center py-2 hover:bg-gray-100 dark:hover:bg-[#373f59]"
> >
@ -162,7 +164,7 @@ const changeOpen = (index: Number) => {
</div> </div>
<div <div
v-if="item?.badgeContent" v-if="item?.badgeContent"
class="mr-6 badge badge-sm badge-primary" class="mr-6 badge badge-sm" :class="item?.badgeClass"
> >
{{ item?.badgeContent }} {{ item?.badgeContent }}
</div> </div>
@ -174,6 +176,45 @@ const changeOpen = (index: Number) => {
{{ item?.heading }} {{ item?.heading }}
</div> </div>
</div> </div>
<div>
<div class="px-4 text-sm pt-4 text-gray-400 pb-2 uppercase">
Sponsors
</div>
<a href="https://osmosis.zone" class="collapse-title px-4 flex items-center py-2 hover:bg-gray-100 dark:hover:bg-[#373f59]">
<img src="https://ping.pub/logos/osmosis.jpg" class="w-6 h-6 rounded-full mr-3"/>
<div class="text-base capitalize flex-1 text-gray-700 dark:text-gray-200">
Osmosis
</div>
</a>
<a href="https://becole.com" class="collapse-title px-4 flex items-center py-2 hover:bg-gray-100 dark:hover:bg-[#373f59]">
<img src="https://becole.com/static/logo/logo_becole.png" class="w-6 h-6 rounded-full mr-3"/>
<div class="text-base capitalize flex-1 text-gray-700 dark:text-gray-200">
Becole
</div>
</a>
<div class="px-4 text-sm pt-4 text-gray-400 pb-2 uppercase">
Links
</div>
<a href="https://twitter.com/ping_pub" class="collapse-title px-4 flex items-center py-2 hover:bg-gray-100 dark:hover:bg-[#373f59]">
<Icon icon="mdi:twitter" class="text-xl mr-2"/>
<div class="text-base capitalize flex-1 text-gray-700 dark:text-gray-200">
Twitter
</div>
</a>
<a v-if="showDiscord" href="https://discord.com/invite/CmjYVSr6GW" class="collapse-title px-4 flex items-center py-2 hover:bg-gray-100 dark:hover:bg-[#373f59]">
<Icon icon="mdi:discord" class="text-xl mr-2"/>
<div class="text-base capitalize flex-1 text-gray-700 dark:text-gray-200">
Discord
</div>
</a>
<a href="https://github.com/ping-pub/explorer/discussions" class="collapse-title px-4 flex items-center py-2 hover:bg-gray-100 dark:hover:bg-[#373f59]">
<Icon icon="mdi:frequently-asked-questions" class="text-xl mr-2"/>
<div class="text-base capitalize flex-1 text-gray-700 dark:text-gray-200">
FAQ
</div>
</a>
</div>
</div> </div>
<div class="xl:ml-64 px-5"> <div class="xl:ml-64 px-5">
<!-- header --> <!-- header -->

View File

@ -8,6 +8,10 @@ const tab = ref('blocks');
const base = useBaseStore() const base = useBaseStore()
const format = useFormatter(); const format = useFormatter();
const list = computed(() => {
return base.recents.reverse()
})
</script> </script>
<template> <template>
<div> <div>
@ -26,34 +30,28 @@ const format = useFormatter();
> >
</div> </div>
<div v-show="tab === 'blocks'" class="bg-base-100 rounded overflow-x-auto"> <div v-show="tab === 'blocks'" class="grid xl:grid-cols-6 md:grid-cols-4 grid-cols-1">
<table class="table w-full table-compact">
<thead> <RouterLink
<tr> v-for="item in list"
<th style="position: relative; z-index: 2;">Height</th> class="flex flex-col justify-between rounded border border-gray-100 m-2 p-4 shadow-xl bg-base-100"
<th>Hash</th> :to="`/${chain}/block/${item.block.header.height}`"
<th>Proposer</th> >
<th>Txs</th> <div class="flex justify-between">
<th>Time</th> <h3 class="text-md font-bold sm:text-lg">
</tr> {{ item.block.header.height }}
</thead> </h3>
<tbody v-if="base.recents && base.recents.length > 0" > <span class="rounded text-xs whitespace-nowrap font-medium text-green-600">
<tr v-for="(item, index) in base.recents" :key="index"> {{ format.toDay(item.block?.header?.time, 'from') }}
<td class="text-sm text-primary"> </span>
<RouterLink </div>
:to="`/${props.chain}/block/${item.block?.header?.height}`" <div class="flex justify-between">
>{{ item.block?.header?.height }}</RouterLink <p class="mt-2 hidden text-sm sm:block truncate">
> {{ format.validator(item.block?.header?.proposer_address) }}
</td> </p>
<td>{{ item.block_id?.hash }}</td> <span class="text-right mt-1 whitespace-nowrap"> {{ item.block?.data?.txs.length }} txs </span>
<td> </div>
{{ format.validator(item.block?.header?.proposer_address) }} </RouterLink>
</td>
<td>{{ item.block?.data?.txs.length }}</td>
<td>{{ format.toDay(item.block?.header?.time, 'from') }}</td>
</tr>
</tbody>
</table>
</div> </div>
<div <div

View File

@ -26,6 +26,7 @@ const slashingParam = ref({} as SlashingParam)
const signingInfo = ref({} as Record<string, SigningInfo>); const signingInfo = ref({} as Record<string, SigningInfo>);
const filterOptout =ref(false)
// filter validators by keywords // filter validators by keywords
const validators = computed(() => { const validators = computed(() => {
if (keyword) if (keyword)
@ -37,7 +38,7 @@ const validators = computed(() => {
const list = computed(() => { const list = computed(() => {
const window = Number(slashingParam.value.signed_blocks_window|| 0) const window = Number(slashingParam.value.signed_blocks_window|| 0)
return validators.value.map(v => { const vset = validators.value.map(v => {
const signing = signingInfo.value[consensusPubkeyToHexAddress(v.consensus_pubkey)] const signing = signingInfo.value[consensusPubkeyToHexAddress(v.consensus_pubkey)]
return { return {
v, v,
@ -45,6 +46,7 @@ const list = computed(() => {
hex: toBase64(fromHex(consensusPubkeyToHexAddress(v.consensus_pubkey))), hex: toBase64(fromHex(consensusPubkeyToHexAddress(v.consensus_pubkey))),
uptime: signing && window > 0 ? (window - Number(signing.missed_blocks_counter)) / window: undefined uptime: signing && window > 0 ? (window - Number(signing.missed_blocks_counter)) / window: undefined
}}) }})
return filterOptout.value? vset.filter(x => x.signing) : vset
}) })
onMounted(() => { onMounted(() => {
@ -98,7 +100,6 @@ const tab = ref("3")
function changeTab(v: string) { function changeTab(v: string) {
tab.value = v tab.value = v
} }
</script> </script>
<template> <template>
@ -124,6 +125,10 @@ function changeTab(v: string) {
</div> </div>
<div class="bg-base-100 px-5 pt-5"> <div class="bg-base-100 px-5 pt-5">
<div class="flex items-center gap-x-4"> <div class="flex items-center gap-x-4">
<label v-if="chainStore.isConsumerChain" class="text-center">
<input type="checkbox" v-model="filterOptout" class="checkbox"/>
Only Consumer Set
</label>
<input type="text" v-model="keyword" placeholder="Keywords to filter validators" <input type="text" v-model="keyword" placeholder="Keywords to filter validators"
class="input input-sm w-full flex-1" /> class="input input-sm w-full flex-1" />
</div> </div>
@ -150,28 +155,28 @@ function changeTab(v: string) {
<tr> <tr>
<td>Validator</td> <td>Validator</td>
<td class="text-right">Uptime</td> <td class="text-right">Uptime</td>
<td>Last Jailed Time</td>
<td class="text-right">Signed Precommits</td> <td class="text-right">Signed Precommits</td>
<td class="text-right">Start Height</td> <td class="text-right">Start Height</td>
<td>Last Jailed Time</td>
<td>Tombstoned</td> <td>Tombstoned</td>
</tr> </tr>
</thead> </thead>
<tr v-for="({v, signing, uptime}, i) in list" class="hover"> <tr v-for="({v, signing, uptime}, i) in list" class="hover">
<td><div class="truncate max-w-sm">{{ i+1 }}. {{ v.description.moniker }}</div></td> <td><div class="truncate max-w-sm">{{ i+1 }}. {{ v.description.moniker }}</div></td>
<td class="text-right"> <td class="text-right">
<span v-if="signing" class="" :class="uptime > 0.95 ? 'text-green-500':'text-red-500'"><div class="tooltip" :data-tip="`${signing.missed_blocks_counter} missing blocks`"> {{ format.percent(uptime) }} </div> </span> <span v-if="signing" class="" :class="uptime && uptime > 0.95 ? 'text-green-500':'text-red-500'"><div class="tooltip" :data-tip="`${signing.missed_blocks_counter} missing blocks`"> {{ format.percent(uptime) }} </div> </span>
</td> </td>
<td><span v-if="signing && !signing.jailed_until.startsWith('1970')">
<div class="tooltip" :data-tip="format.toDay(signing?.jailed_until, 'long')">
<span>{{ format.toDay(signing?.jailed_until, "from") }}</span>
</div>
</span></td>
<td class="text-right text-xs"> <td class="text-right text-xs">
{{ signing?.index_offset }}<br> {{ signing?.index_offset }}<br>
<span v-if="signing && signing.jailed_until.startsWith('1970')" class="text-xs">{{ format.percent(Number(signing.index_offset)/(latest-Number(signing.start_height))) }}</span> <span v-if="signing && signing.jailed_until.startsWith('1970')" class="text-xs">{{ format.percent(Number(signing.index_offset)/(latest-Number(signing.start_height))) }}</span>
</td> </td>
<td class="text-right">{{ signing?.start_height }}</td> <td class="text-right">{{ signing?.start_height }}</td>
<td><span v-if="signing && !signing.jailed_until.startsWith('1970')">
<div class="tooltip" :data-tip="format.toDay(signing?.jailed_until, 'long')">
<span>{{ format.toDay(signing?.jailed_until, "from") }}</span>
</div>
</span></td>
<td class=" capitalize">{{ signing?.tombstoned }}</td> <td class=" capitalize">{{ signing?.tombstoned }}</td>
</tr> </tr>
<tfoot> <tfoot>

View File

@ -33,7 +33,7 @@ const hdPath = computed(() => {
</div> </div>
<span class="text-base">Import global script </span> <span class="text-base">Import global script </span>
<div class="mockup-code my-2"> <div class="mockup-code my-2">
<pre data-prefix="1"><code>&lt;script src="https://unpkg.com/ping-widget@latest/dist/ping-widget.js"&gt;</code></pre> <pre data-prefix="1"><code class="text-gray-400">&lt;script type="module" src="https://unpkg.com/ping-widget@latest/dist/ping-widget.js"&gt;</code></pre>
</div> </div>
</div> </div>
<div class="bg-base-100 my-5 px-4 pt-3 pb-4 rounded shadow"> <div class="bg-base-100 my-5 px-4 pt-3 pb-4 rounded shadow">
@ -41,12 +41,13 @@ const hdPath = computed(() => {
<div class="mt-4"> <div class="mt-4">
<span class="text-base"> 1. Connect Wallet </span> <span class="text-base"> 1. Connect Wallet </span>
<div class="mockup-code my-2"> <div class="mockup-code my-2">
<pre data-prefix=">"><code>&lt;ping-connect-wallet chain-id="{{ chainId }}" hd-path="{{ hdPath }}"/&gt;</code></pre> <pre data-prefix=">"><code class="text-gray-400">&lt;ping-connect-wallet chain-id="{{ chainId }}" hd-path="{{ hdPath }}"/&gt;</code></pre>
</div> </div>
<span class="text-base"> 2. Osmosis Convert </span> <span class="text-base"> 2. Osmosis Convert </span>
<div class="mockup-code my-2"> <div class="mockup-code my-2">
<pre data-prefix=">"><code>&lt;ping-token-convert chain-name="{{ chainName }}" endpoint="{{endpoint}}" hd-path="hdPath"/&gt;</code></pre> <pre data-prefix=">"><code class="text-gray-400">&lt;ping-token-convert chain-name="{{ chainName }}" endpoint="{{endpoint}}" hd-path="{{hdPath}}"/&gt;</code></pre>
<pre data-prefix=">"><code class="text-gray-400">&lt;label for="PingTokenConvert" class="btn btn-sm"&gt;Buy {{chainName.toUpperCase()}}&lt;/label&gt;</code></pre>
</div> </div>
</div> </div>
</div> </div>
@ -57,7 +58,7 @@ const hdPath = computed(() => {
{ {
meta: { meta: {
i18n: 'widget', i18n: 'widget',
order: 9 order: 300
} }
} }
</route> </route>

View File

@ -9,6 +9,7 @@ import type { NavGroup, NavLink, NavSectionTitle, VerticalNavItems } from '@layo
import { themeConfig as config } from '@themeConfig' import { themeConfig as config } from '@themeConfig'
console.log("v nav")
interface Props { interface Props {
tag?: string | Component tag?: string | Component
navItems: VerticalNavItems navItems: VerticalNavItems

View File

@ -8,6 +8,7 @@ export const openGroups = ref<string[]>([])
* @param {Object, String} item navigation routeName or route Object provided in navigation data * @param {Object, String} item navigation routeName or route Object provided in navigation data
*/ */
export const getComputedNavLinkToProp = computed(() => (link: NavLink) => { export const getComputedNavLinkToProp = computed(() => (link: NavLink) => {
console.log(link)
const props: NavLinkProps = { const props: NavLinkProps = {
target: link.target, target: link.target,
rel: link.rel, rel: link.rel,

View File

@ -78,7 +78,7 @@ export const useBaseStore = defineStore('baseStore', {
) === -1 ) === -1
) { ) {
if (this.recents.length >= 50) { if (this.recents.length >= 50) {
this.recents.pop(); this.recents.shift();
} }
this.recents.push(this.latest); this.recents.push(this.latest);
} }

View File

@ -68,7 +68,7 @@ export const useBlockchain = defineStore('blockchain', {
icon: { image: this.current.logo, size: '22' }, icon: { image: this.current.logo, size: '22' },
i18n: false, i18n: false,
badgeContent: this.isConsumerChain? 'Consumer': undefined, badgeContent: this.isConsumerChain? 'Consumer': undefined,
badgeClass: 'bg-warning', badgeClass: 'bg-error',
children: routes children: routes
.filter((x) => x.meta.i18n) // defined menu name .filter((x) => x.meta.i18n) // defined menu name
.filter((x) => !this.current?.features || this.current.features.includes(String(x.meta.i18n))) // filter none-custom module .filter((x) => !this.current?.features || this.current.features.includes(String(x.meta.i18n))) // filter none-custom module