Skip to content

Commit

Permalink
feat: load space's custom colors (#1090)
Browse files Browse the repository at this point in the history
* feat: apply custom colors from space

* feat: load dark/light theme for skin

* feat: disable dark/light theme toggler on custom skin

* refactor: use a dedicated function to set skin

* refactor: fix types

---------

Co-authored-by: Chaitanya <[email protected]>
  • Loading branch information
wa0x6e and ChaituVR authored Jan 30, 2025
1 parent d777800 commit 02085bb
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 12 deletions.
7 changes: 6 additions & 1 deletion apps/ui/src/components/App/Topnav.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const { modalAccountOpen, modalAccountWithoutDismissOpen, resetAccountModal } =
useModal();
const { login, web3 } = useWeb3();
const { toggleSkin, currentMode } = useUserSkin();
const { isWhiteLabel } = useWhiteLabel();
const SEARCH_CONFIG = {
space: {
Expand Down Expand Up @@ -149,7 +150,11 @@ onUnmounted(() => {
</template>
</UiButton>
<IndicatorPendingTransactions />
<UiButton class="!px-0 w-[46px]" @click="toggleSkin">
<UiButton
v-if="!isWhiteLabel"
class="!px-0 w-[46px]"
@click="toggleSkin()"
>
<IH-light-bulb v-if="currentMode === 'dark'" class="inline-block" />
<IH-moon v-else class="inline-block" />
</UiButton>
Expand Down
33 changes: 33 additions & 0 deletions apps/ui/src/components/Layout/App.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
<script lang="ts" setup>
import resolveConfig from 'tailwindcss/resolveConfig';
import { Skin } from '@/composables/useUserSkin';
import { APP_NAME } from '@/helpers/constants';
import {
clone,
getCacheHash,
getStampUrl,
hexToRgb,
whiteLabelAwareParams
} from '@/helpers/utils';
import { Transaction } from '@/types';
Expand All @@ -21,6 +24,7 @@ const router = useRouter();
const uiStore = useUiStore();
const { modalOpen } = useModal();
const { init, setAppName, app } = useApp();
const { DEFAULT_SKIN, setSkin } = useUserSkin();
const { isWhiteLabel, space: whiteLabelSpace } = useWhiteLabel();
const { setFavicon } = useFavicon();
const { web3 } = useWeb3();
Expand All @@ -42,6 +46,7 @@ const {
transaction,
reset
} = useWalletConnectTransaction();
const { css } = useStyleTag('', { id: 'skin' });
provide('web3', web3);
Expand All @@ -67,6 +72,25 @@ const hasTopNav = computed(() => {
return 'space-editor' !== String(route.matched[1]?.name);
});
const skinVariables = computed(() => {
if (!whiteLabelSpace.value?.additionalRawData?.skinSettings) return {};
const colors = clone(whiteLabelSpace.value?.additionalRawData?.skinSettings);
const result = Object.entries(colors).reduce((acc, [colorName, hex]) => {
if (!hex || !colorName.includes('_color')) return acc;
const rgb = hexToRgb(hex.slice(1));
acc[`--${colorName.replace('_color', '')}`] = `${rgb.r},${rgb.g},${rgb.b}`;
return acc;
}, {});
if (result['--content']) {
result['--content'] = `rgb(${result['--content']})`;
}
return result;
});
async function handleTransactionAccept() {
if (
!walletConnectSpaceKey.value ||
Expand Down Expand Up @@ -145,6 +169,15 @@ watch(
setFavicon(faviconUrl);
setAppName(whiteLabelSpace.value.name);
css.value = `:root { ${Object.entries(skinVariables.value)
.map(([key, val]) => `${key}:${val}`)
.join(';')}; }`;
setSkin(
(whiteLabelSpace.value.additionalRawData?.skinSettings?.theme as Skin) ||
DEFAULT_SKIN
);
},
{ immediate: true }
);
Expand Down
8 changes: 1 addition & 7 deletions apps/ui/src/components/Ui/ProposalLabel.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script setup lang="ts">
import { RouteLocationNamedRaw } from 'vue-router';
import { hexToRgb } from '@/helpers/utils';
const props = defineProps<{
label: string;
Expand All @@ -11,13 +12,6 @@ const { currentMode } = useUserSkin();
const colorProperties = computed(() => checkColorProximity(props.color));
function hexToRgb(hex: string): { r: number; g: number; b: number } {
const r = parseInt(hex.substring(0, 2), 16);
const g = parseInt(hex.substring(2, 4), 16);
const b = parseInt(hex.substring(4, 6), 16);
return { r, g, b };
}
function checkColorProximity(color: string): {
backgroundColor?: string;
showBorder: boolean;
Expand Down
16 changes: 12 additions & 4 deletions apps/ui/src/composables/useUserSkin.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,33 @@
type Skin = 'dark' | 'light' | 'none';
export type Skin = 'dark' | 'light' | 'none';

const DEFAULT_SKIN = 'light';

export function useUserSkin() {
const store = useStorage<Skin>('skin', 'none');
const currentMode = computed(() =>
['light', 'none'].includes(store.value) ? 'light' : 'dark'
[DEFAULT_SKIN, 'none'].includes(store.value) ? DEFAULT_SKIN : 'dark'
);

function toggleSkin() {
store.value = ['light', 'none'].includes(store.value) ? 'dark' : 'light';
}

function setSkin(skin: Skin) {
store.value = skin;
}

watchEffect(() => {
if (currentMode.value === 'light') {
if (currentMode.value === DEFAULT_SKIN) {
document.documentElement.classList.remove('dark');
} else {
document.documentElement.classList.add('dark');
}
});

return {
DEFAULT_SKIN,
currentMode,
toggleSkin
toggleSkin,
setSkin
};
}
7 changes: 7 additions & 0 deletions apps/ui/src/helpers/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -637,3 +637,10 @@ export function whiteLabelAwareParams(

return params;
}

export function hexToRgb(hex: string): { r: number; g: number; b: number } {
const r = parseInt(hex.substring(0, 2), 16);
const g = parseInt(hex.substring(2, 4), 16);
const b = parseInt(hex.substring(4, 6), 16);
return { r, g, b };
}
1 change: 1 addition & 0 deletions apps/ui/src/networks/offchain/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ function formatSpace(
private: space.private,
domain: space.domain,
skin: space.skin,
skinSettings: space.skinSettings,
strategies: space.strategies,
categories: space.categories,
admins: space.admins,
Expand Down
10 changes: 10 additions & 0 deletions apps/ui/src/networks/offchain/api/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,16 @@ const SPACE_FRAGMENT = gql`
private
domain
skin
skinSettings {
bg_color
link_color
text_color
content_color
border_color
heading_color
primary_color
theme
}
guidelines
template
categories
Expand Down
2 changes: 2 additions & 0 deletions apps/ui/src/networks/offchain/api/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
DelegationType,
NetworkID,
SkinSettings,
SpaceMetadataLabel,
VoteType
} from '@/types';
Expand Down Expand Up @@ -77,6 +78,7 @@ export type ApiSpace = {
private: boolean;
domain: string | null;
skin: string | null;
skinSettings: SkinSettings | null;
template: string | null;
guidelines: string | null;
categories: string[];
Expand Down
12 changes: 12 additions & 0 deletions apps/ui/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ export type OffchainAdditionalRawData = {
| 'private'
| 'domain'
| 'skin'
| 'skinSettings'
| 'strategies'
| 'categories'
| 'admins'
Expand Down Expand Up @@ -393,6 +394,17 @@ export type Metadata = {
execution: Transaction[];
};

export type SkinSettings = {
bg_color?: string;
link_color?: string;
text_color?: string;
content_color?: string;
border_color?: string;
heading_color?: string;
primary_color?: string;
theme?: string;
};

export type Drafts = Record<string, Draft>;

export type BaseTransaction = {
Expand Down

0 comments on commit 02085bb

Please sign in to comment.