feat: chart theme switch

This commit is contained in:
Alisa | Side.one 2023-05-28 09:19:39 +08:00
parent b10578e680
commit 2f93b4c10c
6 changed files with 230 additions and 237 deletions

View File

@ -1,50 +0,0 @@
<script setup lang="ts">
import { Icon } from '@iconify/vue';
import { onMounted, ref } from 'vue';
const props = defineProps<{
themes: {
name: string;
icon: string;
}[];
}>();
const themeMap = { system: 'mdi-laptop', light: 'mdi-weather-sunny', dark: 'mdi-weather-night' }
const theme = ref(window.localStorage.getItem('theme') || 'dark');
const changeMode = () => {
let value = 'dark';
if (theme.value === 'dark') {
value = 'light';
}
if (
theme.value === 'system' &&
window.matchMedia('(prefers-color-scheme: dark)').matches
) {
value = 'dark';
}
if (value === 'light') {
document.documentElement.classList.add('light');
document.documentElement.classList.remove('dark');
} else {
document.documentElement.classList.add('dark');
document.documentElement.classList.remove('light');
}
document.documentElement.setAttribute('data-theme', value);
window.localStorage.setItem('theme', value);
};
onMounted(() => {
});
</script>
<template>
<div class="tooltip tooltip-bottom delay-1000">
<button class=" btn btn-ghost btn-circle btn-sm mx-1" @click="changeMode">
<Icon :icon="props.themes[theme].icon" class="text-2xl" />
</button>
</div>
</template>

View File

@ -1,17 +1,26 @@
<script lang="ts" setup>
import ApexCharts from 'vue3-apexcharts';
import { computed } from 'vue';
import { useBaseStore } from '@/stores';
import { getDonutChartConfig } from './apexChartConfig';
const props = defineProps(['series', 'labels']);
const expenseRationChartConfig = computed(() =>
getDonutChartConfig(window.localStorage.getItem('theme') || 'dark', props.labels)
);
const baseStore = useBaseStore();
const expenseRationChartConfig = computed(() => {
const theme = baseStore.theme;
getDonutChartConfig(theme, props.labels);
});
</script>
<template>
<ApexCharts type="donut" height="410" :options="expenseRationChartConfig" :series="series" />
<ApexCharts
type="donut"
height="410"
:options="expenseRationChartConfig"
:series="series"
/>
</template>
<script lang="ts">

View File

@ -3,11 +3,14 @@ import ApexCharts from 'vue3-apexcharts';
import { getMarketPriceChartConfig } from './apexChartConfig';
import { useIndexModule } from '@/modules/[chain]/indexStore';
import { computed, ref } from '@vue/reactivity';
import { useBaseStore } from '@/stores';
const store = useIndexModule();
const baseStore = useBaseStore();
const chartConfig = computed(() => {
const theme = baseStore.theme;
const labels = store.marketData.prices.map((item: any) => item[0]);
return getMarketPriceChartConfig(window.localStorage.getItem('theme') || 'dark', labels);
return getMarketPriceChartConfig(theme, labels);
});
const kind = ref('price');
const series = computed(() => {
@ -17,7 +20,9 @@ const series = computed(() => {
data:
kind.value === 'price'
? store.marketData.prices.map((item: any) => item[1])
: store.marketData.total_volumes.map((item: any) => item[1]),
: store.marketData.total_volumes.map(
(item: any) => item[1]
),
},
];
});
@ -29,14 +34,25 @@ function changeChart(type: string) {
<template>
<div class="tabs tabs-boxed bg-transparent justify-end">
<a class="tab text-xs mr-2 text-gray-400 uppercase" :class="{ 'tab-active': kind === 'price' }"
@click="changeChart('price')">
<a
class="tab text-xs mr-2 text-gray-400 uppercase"
:class="{ 'tab-active': kind === 'price' }"
@click="changeChart('price')"
>
Price
</a>
<a class="tab text-xs text-gray-400 uppercase" :class="{ 'tab-active': kind === 'volume' }"
@click="changeChart('volume')">
<a
class="tab text-xs text-gray-400 uppercase"
:class="{ 'tab-active': kind === 'volume' }"
@click="changeChart('volume')"
>
Volume
</a>
</div>
<ApexCharts type="area" height="230" :options="chartConfig" :series="series" />
<ApexCharts
type="area"
height="230"
:options="chartConfig"
:series="series"
/>
</template>

View File

@ -34,11 +34,16 @@ const handleLangChange = (lang: string) => {
<div
class="dropdown"
:class="
currentLang === 'ar' ? 'dropdown-right' : 'dropdown-bottom dropdown-end'
currentLang === 'ar'
? 'dropdown-right'
: 'dropdown-bottom dropdown-end'
"
>
<label tabindex="0" class="btn btn-ghost btn-circle btn-sm mx-1">
<Icon icon="mdi-translate" class="text-2xl" />
<Icon
icon="mdi-translate"
class="text-2xl text-gray-500 dark:text-gray-400"
/>
</label>
<ul
tabindex="0"

View File

@ -1,23 +1,24 @@
<script setup lang="ts">
import { Icon } from '@iconify/vue';
import { onMounted, ref } from 'vue';
import { onMounted, computed } from 'vue';
import { useBaseStore } from '@/stores';
const themeMap: Record<string, string> = { system: 'mdi-laptop', light: 'mdi-weather-sunny', dark: 'mdi-weather-night' }
const themeMap: Record<string, string> = {
system: 'mdi-laptop',
light: 'mdi-weather-sunny',
dark: 'mdi-weather-night',
};
const baseStore = useBaseStore();
const theme = computed(() => {
return baseStore.theme;
});
const theme = ref(window.localStorage.getItem('theme') || 'dark');
const changeMode = (val?: string) => {
let value = 'dark';
const currentValue = val || theme.value;
const changeMode = (val?: 'dark' | 'light') => {
let value: 'dark' | 'light' = 'dark';
const currentValue: 'dark' | 'light' = val || theme.value;
if (currentValue === 'dark') {
value = 'light';
}
if (
currentValue === 'system' &&
window.matchMedia('(prefers-color-scheme: dark)').matches
) {
value = 'dark';
}
if (value === 'light') {
document.documentElement.classList.add('light');
document.documentElement.classList.remove('dark');
@ -27,10 +28,9 @@ const changeMode = (val?: string) => {
}
document.documentElement.setAttribute('data-theme', value);
window.localStorage.setItem('theme', value);
theme.value = value;
baseStore.theme = value;
};
onMounted(() => {
changeMode(theme.value === 'light' ? 'dark' : 'light');
});
@ -38,8 +38,11 @@ onMounted(() => {
<template>
<div class="tooltip tooltip-bottom delay-1000">
<button class=" btn btn-ghost btn-circle btn-sm mx-1" @click="changeMode()">
<Icon :icon="themeMap?.[theme]" class="text-2xl" />
<button
class="btn btn-ghost btn-circle btn-sm mx-1"
@click="changeMode()"
>
<Icon :icon="themeMap?.[theme]" class="text-2xl text-gray-500 dark:text-gray-400" />
</button>
</div>
</template>

View File

@ -12,6 +12,9 @@ export const useBaseStore = defineStore('baseStore', {
earlest: {} as Block,
latest: {} as Block,
recents: [] as Block[],
theme: (window.localStorage.getItem('theme') || 'dark') as
| 'light'
| 'dark',
};
},
getters: {
@ -33,10 +36,14 @@ export const useBaseStore = defineStore('baseStore', {
return useBlockchain();
},
currentChainId(): string {
return this.latest.block?.header.chain_id || ""
return this.latest.block?.header.chain_id || '';
},
txsInRecents() {
const txs = [] as { height: string; hash: string; tx: DecodedTxRaw }[];
const txs = [] as {
height: string;
hash: string;
tx: DecodedTxRaw;
}[];
this.recents.forEach((b) =>
b.block?.data?.txs.forEach((tx: string) => {
if (tx) {
@ -89,7 +96,10 @@ export const useBaseStore = defineStore('baseStore', {
},
async fetchValidatorByHeight(height?: number, offset = 0) {
return this.blockchain.rpc.getBaseValidatorsetAt(String(height), offset);
return this.blockchain.rpc.getBaseValidatorsetAt(
String(height),
offset
);
},
async fetchLatestValidators(offset = 0) {
return this.blockchain.rpc.getBaseValidatorsetLatest(offset);