Skip to content

Commit

Permalink
Merge pull request #439 from gobitfly/BIDS-3115/improves-network-iden…
Browse files Browse the repository at this point in the history
…tification

(BIDS-3115) Now users can identify better the network in use
  • Loading branch information
thib-wien authored Jun 12, 2024
2 parents d923c5c + 0c0215a commit 4645eee
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 49 deletions.
43 changes: 33 additions & 10 deletions frontend/components/bc/header/MainHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,14 @@ const userMenu = computed(() => {
<FontAwesomeIcon :icon="faBars" class="burger" @click.stop.prevent="toggleMegaMenu" />
</div>

<div class="grid-cell logo">
<BcLink to="/" class="logo-component">
<div class="grid-cell explorer-info">
<BcLink to="/" class="logo">
<IconBeaconchainLogo alt="Beaconcha.in logo" />
beaconcha.in
<span class="name">beaconcha.in</span>
</BcLink>
<span class="variant">
v2 beta | {{ networkInfo.name }}
</span>
</div>

<div class="grid-cell mega-menu">
Expand All @@ -136,7 +139,7 @@ const userMenu = computed(() => {
@use "~/assets/css/fonts.scss";
// do not change these two values without changing the values in types/header.ts accordingly
$mobileHeaderThreshold: 470px;
$mobileHeaderThreshold: 600px;
$smallHeaderThreshold: 1024px;
.anchor {
Expand Down Expand Up @@ -278,34 +281,54 @@ $smallHeaderThreshold: 1024px;
}
}
.logo {
.explorer-info {
grid-column: 2;
@media (min-width: $smallHeaderThreshold) {
@include bottom-cell(2);
}
@media (max-width: $smallHeaderThreshold) {
grid-row: 1;
}
.logo-component {
height: unset;
.logo {
display: flex;
align-items: flex-end;
position: relative;
margin-top: auto;
gap: var(--padding);
font-family: var(--logo_font_family);
font-size: var(--logo_font_size);
font-weight: var(--logo_font_weight);
letter-spacing: var(--logo_letter_spacing);
line-height: 20px;
svg {
margin-top: auto;
}
.name {
display: inline-flex;
position: relative;
margin-top: auto;
line-height: 22px;
}
@media (max-width: 1359px) {
font-size: var(--logo_small_font_size);
letter-spacing: var(--logo_small_letter_spacing);
gap: 6px;
align-items: center;
.name {
line-height: 14px;
}
svg {
height: 18px;
margin-bottom: 7px;
}
}
}
.variant {
position: relative;
margin-top: auto;
line-height: 10px;
font-size: var(--tiny_text_font_size);
color: var(--megamenu-text-color);
}
}
.mega-menu {
Expand Down
2 changes: 2 additions & 0 deletions frontend/components/bc/toggle/SingleBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ interface Props {
buttons: {
icon?: IconDefinition,
text?: string,
subText?: string,
component?: Component,
componentProps?: any,
componentClass?: string,
Expand Down Expand Up @@ -44,6 +45,7 @@ function onButtonClicked (value: string) {
:key="button.value"
:icon="button.icon"
:text="button.text"
:sub-text="button.subText"
:selected="values[button.value]"
:disabled="button.disabled"
@click="!button.disabled && onButtonClicked(button.value)"
Expand Down
25 changes: 20 additions & 5 deletions frontend/components/bc/toggle/SingleBarButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,28 @@ import type { IconDefinition } from '@fortawesome/fontawesome-svg-core'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
interface Props {
icon?: IconDefinition,
text?: string
text?: string,
subText?: string,
selected: boolean,
disabled?:boolean,
}
defineProps<Props>()
const props = defineProps<Props>()
const topBottomPadding = computed(() => props.subText ? '8px' : '16px')
</script>

<template>
<ToggleButton class="bc-toggle" :disabled="disabled" :model-value="selected" :on-label="text" :off-label="text">
<ToggleButton class="bc-toggle" :disabled="disabled" :model-value="selected">
<template #icon="slotProps">
<slot name="icon" v-bind="slotProps">
<FontAwesomeIcon v-if="icon" :icon="icon" />
</slot>
<div class="label">
{{ text }}
<div v-if="subText" class="sub">
{{ subText }}
</div>
</div>
</template>
</ToggleButton>
</template>
Expand All @@ -34,7 +42,7 @@ defineProps<Props>()
width: 100%;
height: 100%;
padding: 16px 0 15px 0;
padding: v-bind(topBottomPadding) 0;
border: 1px var(--container-border-color) solid;
border-radius: var(--border-radius);
background-color: var(--container-background);
Expand All @@ -46,7 +54,7 @@ defineProps<Props>()
}
:deep(.p-button-label) {
@include fonts.subtitle_text;
display: none;
}
:deep(svg) {
Expand All @@ -58,5 +66,12 @@ defineProps<Props>()
}
}
}
.label {
@include fonts.subtitle_text;
.sub {
font-size: var(--tiny_text_font_size);
}
}
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ watch(selection, (value) => { network.value = Number(value) as ChainIDs })
const buttonList = ValidatorDashboardNetworkList.map((chainId) => {
return {
value: String(chainId),
text: ChainInfo[chainId].name,
text: ChainInfo[chainId].family as string,
subText: (ChainInfo[chainId].name !== ChainInfo[chainId].family as string) ? ChainInfo[chainId].name : ChainInfo[chainId].description,
disabled: !useRuntimeConfig().public.showInDevelopment && chainId !== currentNetwork.value, // TODO: simply set `false` for everything once dashboards can be created for all the networks in `ValidatorDashboardNetworkList`
component: IconNetwork,
componentProps: { chainId, colored: false },
componentProps: { chainId, colored: false, harmonizePerceivedSize: true },
componentClass: 'dashboard-creation-button-network-icon'
}
})
Expand Down
3 changes: 2 additions & 1 deletion frontend/composables/useBcSeo.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export function useBcSeo (pageTitle?: string | Ref<string | number | undefined> | ComputedRef<string | number | undefined>, removeDynamicUrlValue = false) {
const { t: $t } = useI18n()
const route = useRoute()
const { networkInfo } = useNetworkStore()

const year = new Date().getFullYear()

Expand All @@ -23,7 +24,7 @@ export function useBcSeo (pageTitle?: string | Ref<string | number | undefined>
} else if (pageTitle?.value) {
parts.splice(0, 0, `${pageTitle.value}`)
}
return parts.join(' - ')
return networkInfo.value.description + ' ' + networkInfo.value.name + ' ' + parts.join(' - ')
}

useSeoMeta({
Expand Down
29 changes: 12 additions & 17 deletions frontend/stores/useNetworkStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,11 @@ interface ApiChainInfo {

const store = defineStore('network-store', () => {
const data = ref<{
availableNetworks: ApiChainInfo[],
currentNetwork: networkTs.ChainIDs,
currentNetworkHasBeenChosen: boolean
availableNetworks: networkTs.ChainIDs[],
currentNetwork: networkTs.ChainIDs
}>({
// default values if anything wrong happens when the list of available networks is requested from the API
availableNetworks: [{ chain_id: networkTs.ChainIDs.Ethereum, name: networkTs.ChainInfo[networkTs.ChainIDs.Ethereum].name }],
currentNetwork: networkTs.ChainIDs.Ethereum,
currentNetworkHasBeenChosen: false
availableNetworks: [networkTs.ChainIDs.Ethereum],
currentNetwork: networkTs.ChainIDs.Any // this impossible value by defaut must be kept, it ensures that the `computed` of `currentNetwork` selects the network of highest priority when `setCurrentNetwork()` has not been called yet
})
return { data }
})
Expand All @@ -28,28 +25,26 @@ export function useNetworkStore () {
/**
* Needs to be called once, when the front-end is loading. Unnecessary afterwards.
*/
async function loadAvailableNetworks () {
async function loadAvailableNetworks () : Promise<boolean> {
try {
const { fetch } = useCustomFetch()
const list = await fetch<ApiDataResponse<ApiChainInfo[]>>(API_PATH.AVAILABLE_NETWORKS)
data.value.availableNetworks = list.data.sort((a, b) => networkTs.ChainInfo[a.chain_id].priority - networkTs.ChainInfo[b.chain_id].priority)
if (!data.value.currentNetworkHasBeenChosen) {
// by default, the current network is the one with the best priority
data.value.currentNetwork = data.value.availableNetworks[0].chain_id
const response = await fetch<ApiDataResponse<ApiChainInfo[]>>(API_PATH.AVAILABLE_NETWORKS)
if (!response.data || !response.data.length) {
return false
}
data.value.availableNetworks = networkTs.sortChainIDsByPriority(response.data.map(apiInfo => apiInfo.chain_id))
return true
} catch {
return false
}
}

const availableNetworks = computed(() => data.value.availableNetworks.map(apiInfo => apiInfo.chain_id))
const currentNetwork = computed(() => data.value.currentNetwork)
const networkInfo = computed(() => networkTs.ChainInfo[data.value.currentNetwork])
const availableNetworks = computed(() => data.value.availableNetworks)
const currentNetwork = computed(() => availableNetworks.value.includes(data.value.currentNetwork) ? data.value.currentNetwork : availableNetworks.value[0])
const networkInfo = computed(() => networkTs.ChainInfo[currentNetwork.value])

function setCurrentNetwork (chainId: networkTs.ChainIDs) {
data.value.currentNetwork = chainId
data.value.currentNetworkHasBeenChosen = true
}

function isMainNet () : boolean {
Expand Down
2 changes: 1 addition & 1 deletion frontend/types/header.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ If you change these values, you will have to change also some hard-coded equival
For example, in MainHeader.vue, these two definitions are repeated in the <style> section because @media
queries do not accept to be bound with JS variables.
*/
export const mobileHeaderThreshold = 470
export const mobileHeaderThreshold = 600
export const smallHeaderThreshold = 1024
26 changes: 13 additions & 13 deletions frontend/types/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export const ChainInfo: Record<ChainIDs, ChainInfoFields> = {

[ChainIDs.Ethereum]: {
name: 'Ethereum',
description: 'Ethereum Mainnet',
description: 'Mainnet',
family: ChainFamily.Ethereum,
mainNet: ChainIDs.Ethereum,
L1: ChainIDs.Ethereum,
Expand All @@ -77,7 +77,7 @@ export const ChainInfo: Record<ChainIDs, ChainInfoFields> = {
},
[ChainIDs.Holesky]: {
name: 'Holesky',
description: 'Holesky Testnet',
description: 'Testnet',
family: ChainFamily.Ethereum,
mainNet: ChainIDs.Ethereum,
L1: ChainIDs.Holesky,
Expand All @@ -91,7 +91,7 @@ export const ChainInfo: Record<ChainIDs, ChainInfoFields> = {
},
[ChainIDs.Sepolia]: {
name: 'Sepolia',
description: 'Sepolia Testnet',
description: 'Testnet',
family: ChainFamily.Ethereum,
mainNet: ChainIDs.Ethereum,
L1: ChainIDs.Sepolia,
Expand All @@ -106,7 +106,7 @@ export const ChainInfo: Record<ChainIDs, ChainInfoFields> = {

[ChainIDs.ArbitrumOneEthereum]: {
name: 'Arbitrum One',
description: 'Arbitrum One L2',
description: 'L2',
family: ChainFamily.Arbitrum,
mainNet: ChainIDs.ArbitrumOneEthereum,
L1: ChainIDs.Ethereum,
Expand All @@ -120,7 +120,7 @@ export const ChainInfo: Record<ChainIDs, ChainInfoFields> = {
},
[ChainIDs.ArbitrumNovaEthereum]: {
name: 'Arbitrum Nova',
description: 'Arbitrum Nova L2',
description: 'L2',
family: ChainFamily.Arbitrum,
mainNet: ChainIDs.ArbitrumNovaEthereum,
L1: ChainIDs.Ethereum,
Expand All @@ -134,7 +134,7 @@ export const ChainInfo: Record<ChainIDs, ChainInfoFields> = {
},
[ChainIDs.ArbitrumOneSepolia]: {
name: 'Arbitrum Sepolia',
description: 'Arbitrum One Sepolia Testnet',
description: 'Testnet',
family: ChainFamily.Arbitrum,
mainNet: ChainIDs.ArbitrumOneEthereum,
L1: ChainIDs.Sepolia,
Expand All @@ -149,7 +149,7 @@ export const ChainInfo: Record<ChainIDs, ChainInfoFields> = {

[ChainIDs.OptimismEthereum]: {
name: 'Optimism',
description: 'Optimism L2',
description: 'L2',
family: ChainFamily.Optimism,
mainNet: ChainIDs.OptimismEthereum,
L1: ChainIDs.Ethereum,
Expand All @@ -163,7 +163,7 @@ export const ChainInfo: Record<ChainIDs, ChainInfoFields> = {
},
[ChainIDs.OptimismSepolia]: {
name: 'Optimism Sepolia',
description: 'Optimism Sepolia Testnet',
description: 'Testnet',
family: ChainFamily.Optimism,
mainNet: ChainIDs.OptimismEthereum,
L1: ChainIDs.Sepolia,
Expand All @@ -178,7 +178,7 @@ export const ChainInfo: Record<ChainIDs, ChainInfoFields> = {

[ChainIDs.BaseEthereum]: {
name: 'Base',
description: 'Base L2',
description: 'L2',
family: ChainFamily.Base,
mainNet: ChainIDs.BaseEthereum,
L1: ChainIDs.Ethereum,
Expand All @@ -192,7 +192,7 @@ export const ChainInfo: Record<ChainIDs, ChainInfoFields> = {
},
[ChainIDs.BaseSepolia]: {
name: 'Base Sepolia',
description: 'Base Sepolia Testnet',
description: 'Testnet',
family: ChainFamily.Base,
mainNet: ChainIDs.BaseEthereum,
L1: ChainIDs.Sepolia,
Expand All @@ -207,7 +207,7 @@ export const ChainInfo: Record<ChainIDs, ChainInfoFields> = {

[ChainIDs.Gnosis]: {
name: 'Gnosis',
description: 'Gnosis',
description: 'Mainnet',
family: ChainFamily.Gnosis,
mainNet: ChainIDs.Gnosis,
L1: ChainIDs.Gnosis,
Expand All @@ -220,8 +220,8 @@ export const ChainInfo: Record<ChainIDs, ChainInfoFields> = {
priority: 40
},
[ChainIDs.Chiado]: {
name: 'Gnosis Chiado',
description: 'Gnosis Chiado Testnet',
name: 'Chiado',
description: 'Testnet',
family: ChainFamily.Gnosis,
mainNet: ChainIDs.Gnosis,
L1: ChainIDs.Chiado,
Expand Down

0 comments on commit 4645eee

Please sign in to comment.